Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(541)

Side by Side Diff: lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp

Issue 791053006: Add support for acquire, release, and acq_rel memory ordering in PNaCl (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Nits. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | lib/Transforms/NaCl/RewriteAtomics.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- PNaClABIVerifyFunctions.cpp - Verify PNaCl ABI rules ---------------===// 1 //===- PNaClABIVerifyFunctions.cpp - Verify PNaCl ABI rules ---------------===//
2 // 2 //
3 // The LLVM Compiler Infrastructure 3 // The LLVM Compiler Infrastructure
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // Verify function-level PNaCl ABI requirements. 10 // Verify function-level PNaCl ABI requirements.
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 const Constant *C = dyn_cast<Constant>(Operation); 138 const Constant *C = dyn_cast<Constant>(Operation);
139 if (!C) 139 if (!C)
140 return false; 140 return false;
141 const APInt &I = C->getUniqueInteger(); 141 const APInt &I = C->getUniqueInteger();
142 if (I.ule(NaCl::AtomicInvalid) || I.uge(NaCl::AtomicNum)) 142 if (I.ule(NaCl::AtomicInvalid) || I.uge(NaCl::AtomicNum))
143 return false; 143 return false;
144 } 144 }
145 return true; 145 return true;
146 } 146 }
147 147
148 static bool hasAllowedAtomicMemoryOrder( 148 static bool
149 const NaCl::AtomicIntrinsics::AtomicIntrinsic *I, const CallInst *Call) { 149 hasAllowedAtomicMemoryOrder(const NaCl::AtomicIntrinsics::AtomicIntrinsic *I,
150 const CallInst *Call) {
151 NaCl::MemoryOrder PreviousOrder = NaCl::MemoryOrderInvalid;
152
150 for (size_t P = 0; P != I->NumParams; ++P) { 153 for (size_t P = 0; P != I->NumParams; ++P) {
151 if (I->ParamType[P] != NaCl::AtomicIntrinsics::Mem) 154 if (I->ParamType[P] != NaCl::AtomicIntrinsics::Mem)
152 continue; 155 continue;
153 156
154 const Value *MemoryOrder = Call->getOperand(P); 157 NaCl::MemoryOrder Order = NaCl::MemoryOrderInvalid;
155 if (!MemoryOrder) 158 if (const Value *MemoryOrderOperand = Call->getOperand(P))
159 if (const Constant *C = dyn_cast<Constant>(MemoryOrderOperand)) {
160 const APInt &I = C->getUniqueInteger();
161 if (I.ugt(NaCl::MemoryOrderInvalid) && I.ult(NaCl::MemoryOrderNum))
162 Order = static_cast<NaCl::MemoryOrder>(I.getLimitedValue());
163 }
164 if (Order == NaCl::MemoryOrderInvalid)
156 return false; 165 return false;
157 const Constant *C = dyn_cast<Constant>(MemoryOrder); 166
158 if (!C) 167 // Validate PNaCl restrictions.
168 switch (Order) {
169 case NaCl::MemoryOrderInvalid:
170 case NaCl::MemoryOrderNum:
171 llvm_unreachable("Invalid memory order");
172 case NaCl::MemoryOrderRelaxed:
173 case NaCl::MemoryOrderConsume:
174 // TODO(jfb) PNaCl doesn't allow relaxed or consume memory ordering.
159 return false; 175 return false;
160 const APInt &I = C->getUniqueInteger(); 176 case NaCl::MemoryOrderAcquire:
161 if (I.ule(NaCl::MemoryOrderInvalid) || I.uge(NaCl::MemoryOrderNum)) 177 case NaCl::MemoryOrderRelease:
162 return false; 178 case NaCl::MemoryOrderAcquireRelease:
163 // TODO For now only sequential consistency is allowed. When more 179 case NaCl::MemoryOrderSequentiallyConsistent:
164 // are allowed we need to validate that the memory order is 180 break; // Allowed by PNaCl.
165 // allowed on the specific atomic operation (e.g. no store 181 }
166 // acquire, and relationship between success/failure memory 182
167 // order on compare exchange). 183 // Validate conformance to the C++11 memory model.
168 if (I != NaCl::MemoryOrderSequentiallyConsistent) 184 switch (I->ID) {
169 return false; 185 default:
186 llvm_unreachable("unexpected atomic operation");
187 case Intrinsic::nacl_atomic_load:
188 // C++11 [atomics.types.operations.req]: The order argument shall not be
189 // release nor acq_rel.
190 if (Order == NaCl::MemoryOrderRelease ||
191 Order == NaCl::MemoryOrderAcquireRelease)
192 return false;
193 break;
194 case Intrinsic::nacl_atomic_store:
195 // C++11 [atomics.types.operations.req]: The order argument shall not be
196 // consume, acquire, nor acq_rel.
197 if (Order == NaCl::MemoryOrderConsume ||
198 Order == NaCl::MemoryOrderAcquire ||
199 Order == NaCl::MemoryOrderAcquireRelease)
200 return false;
201 break;
202 case Intrinsic::nacl_atomic_rmw:
203 break; // No restriction.
204 case Intrinsic::nacl_atomic_cmpxchg:
205 // C++11 [atomics.types.operations.req]: The failure argument shall not be
206 // release nor acq_rel. The failure argument shall be no stronger than the
207 // success argument.
208 // Where the partial ordering is:
209 // relaxed < consume < acquire < acq_rel < seq_cst
210 // relaxed < release < acq_rel < seq_cst
211 if (PreviousOrder != NaCl::MemoryOrderInvalid) { // Failure ordering.
212 NaCl::MemoryOrder Success = PreviousOrder, Failure = Order;
213 if (Failure == NaCl::MemoryOrderRelease ||
214 Failure == NaCl::MemoryOrderAcquireRelease)
215 return false;
216 if ((Success < Failure) || (Success == NaCl::MemoryOrderRelease &&
217 Failure != NaCl::MemoryOrderRelaxed))
218 return false;
219 }
220 break; // Success ordering has no restriction.
221 case Intrinsic::nacl_atomic_fence:
222 case Intrinsic::nacl_atomic_fence_all:
223 break; // No restrictions.
224 }
225
226 PreviousOrder = Order;
170 } 227 }
228
171 return true; 229 return true;
172 } 230 }
173 231
174 static bool hasAllowedLockFreeByteSize(const CallInst *Call) { 232 static bool hasAllowedLockFreeByteSize(const CallInst *Call) {
175 if (!Call->getType()->isIntegerTy()) 233 if (!Call->getType()->isIntegerTy())
176 return false; 234 return false;
177 const Value *Operation = Call->getOperand(0); 235 const Value *Operation = Call->getOperand(0);
178 if (!Operation) 236 if (!Operation)
179 return false; 237 return false;
180 const Constant *C = dyn_cast<Constant>(Operation); 238 const Constant *C = dyn_cast<Constant>(Operation);
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 } 620 }
563 621
564 char PNaClABIVerifyFunctions::ID = 0; 622 char PNaClABIVerifyFunctions::ID = 0;
565 INITIALIZE_PASS(PNaClABIVerifyFunctions, "verify-pnaclabi-functions", 623 INITIALIZE_PASS(PNaClABIVerifyFunctions, "verify-pnaclabi-functions",
566 "Verify functions for PNaCl", false, true) 624 "Verify functions for PNaCl", false, true)
567 625
568 FunctionPass *llvm::createPNaClABIVerifyFunctionsPass( 626 FunctionPass *llvm::createPNaClABIVerifyFunctionsPass(
569 PNaClABIErrorReporter *Reporter) { 627 PNaClABIErrorReporter *Reporter) {
570 return new PNaClABIVerifyFunctions(Reporter); 628 return new PNaClABIVerifyFunctions(Reporter);
571 } 629 }
OLDNEW
« no previous file with comments | « no previous file | lib/Transforms/NaCl/RewriteAtomics.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698