| OLD | NEW | 
|---|
| 1 //===- RewriteAtomics.cpp - Stabilize instructions used for concurrency ---===// | 1 //===- RewriteAtomics.cpp - Stabilize instructions used for concurrency ---===// | 
| 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 // This pass encodes atomics, volatiles and fences using NaCl intrinsics | 10 // This pass encodes atomics, volatiles and fences using NaCl intrinsics | 
| 11 // instead of LLVM's regular IR instructions. | 11 // instead of LLVM's regular IR instructions. | 
| 12 // | 12 // | 
| 13 // All of the above are transformed into one of the | 13 // All of the above are transformed into one of the | 
| 14 // @llvm.nacl.atomic.* intrinsics. | 14 // @llvm.nacl.atomic.* intrinsics. | 
| 15 // | 15 // | 
| 16 //===----------------------------------------------------------------------===// | 16 //===----------------------------------------------------------------------===// | 
| 17 | 17 | 
| 18 #include "llvm/ADT/Twine.h" | 18 #include "llvm/ADT/Twine.h" | 
| 19 #include "llvm/IR/DataLayout.h" | 19 #include "llvm/IR/DataLayout.h" | 
| 20 #include "llvm/IR/Function.h" | 20 #include "llvm/IR/Function.h" | 
| 21 #include "llvm/IR/InlineAsm.h" | 21 #include "llvm/IR/InlineAsm.h" | 
|  | 22 #include "llvm/IR/InstVisitor.h" | 
| 22 #include "llvm/IR/Instructions.h" | 23 #include "llvm/IR/Instructions.h" | 
| 23 #include "llvm/IR/Intrinsics.h" | 24 #include "llvm/IR/Intrinsics.h" | 
| 24 #include "llvm/IR/Module.h" | 25 #include "llvm/IR/Module.h" | 
| 25 #include "llvm/IR/NaClAtomicIntrinsics.h" | 26 #include "llvm/IR/NaClAtomicIntrinsics.h" | 
| 26 #include "llvm/IR/InstVisitor.h" |  | 
| 27 #include "llvm/Pass.h" | 27 #include "llvm/Pass.h" | 
|  | 28 #include "llvm/Support/CommandLine.h" | 
| 28 #include "llvm/Support/Compiler.h" | 29 #include "llvm/Support/Compiler.h" | 
| 29 #include "llvm/Support/raw_ostream.h" | 30 #include "llvm/Support/raw_ostream.h" | 
| 30 #include "llvm/Transforms/NaCl.h" | 31 #include "llvm/Transforms/NaCl.h" | 
| 31 #include <climits> | 32 #include <climits> | 
| 32 #include <string> | 33 #include <string> | 
| 33 | 34 | 
| 34 using namespace llvm; | 35 using namespace llvm; | 
| 35 | 36 | 
|  | 37 // TODO(jfb) Keep the default of this option to true for Chrome 42, and change | 
|  | 38 //           it to false for Chrome 43. This allows the PNaCl translator to be | 
|  | 39 //           updated before the SDK starts emitting atomic memory orders that | 
|  | 40 //           the old translator rejected. | 
|  | 41 static cl::opt<bool> PNaClMemoryOrderSeqCstOnly( | 
|  | 42     "pnacl-memory-order-seq-cst-only", | 
|  | 43     cl::desc("PNaCl should upgrade all atomic memory orders to seq_cst"), | 
|  | 44     cl::init(true)); | 
|  | 45 | 
| 36 namespace { | 46 namespace { | 
|  | 47 | 
| 37 class RewriteAtomics : public ModulePass { | 48 class RewriteAtomics : public ModulePass { | 
| 38 public: | 49 public: | 
| 39   static char ID; // Pass identification, replacement for typeid | 50   static char ID; // Pass identification, replacement for typeid | 
| 40   RewriteAtomics() : ModulePass(ID) { | 51   RewriteAtomics() : ModulePass(ID) { | 
| 41     // This is a module pass because it may have to introduce | 52     // This is a module pass because it may have to introduce | 
| 42     // intrinsic declarations into the module and modify a global function. | 53     // intrinsic declarations into the module and modify a global function. | 
| 43     initializeRewriteAtomicsPass(*PassRegistry::getPassRegistry()); | 54     initializeRewriteAtomicsPass(*PassRegistry::getPassRegistry()); | 
| 44   } | 55   } | 
| 45 | 56 | 
| 46   virtual bool runOnModule(Module &M); | 57   virtual bool runOnModule(Module &M); | 
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 188     // TODO Consume is currently unspecified by LLVM's internal IR. | 199     // TODO Consume is currently unspecified by LLVM's internal IR. | 
| 189     case Acquire: AO = NaCl::MemoryOrderAcquire; break; | 200     case Acquire: AO = NaCl::MemoryOrderAcquire; break; | 
| 190     case Release: AO = NaCl::MemoryOrderRelease; break; | 201     case Release: AO = NaCl::MemoryOrderRelease; break; | 
| 191     case AcquireRelease: AO = NaCl::MemoryOrderAcquireRelease; break; | 202     case AcquireRelease: AO = NaCl::MemoryOrderAcquireRelease; break; | 
| 192     case SequentiallyConsistent: | 203     case SequentiallyConsistent: | 
| 193       AO = NaCl::MemoryOrderSequentiallyConsistent; break; | 204       AO = NaCl::MemoryOrderSequentiallyConsistent; break; | 
| 194     } | 205     } | 
| 195   } | 206   } | 
| 196 | 207 | 
| 197   // TODO For now only acquire/release/acq_rel/seq_cst are allowed. | 208   // TODO For now only acquire/release/acq_rel/seq_cst are allowed. | 
| 198   if (AO == NaCl::MemoryOrderRelaxed) | 209   if (PNaClMemoryOrderSeqCstOnly || AO == NaCl::MemoryOrderRelaxed) | 
| 199     AO = NaCl::MemoryOrderSequentiallyConsistent; | 210     AO = NaCl::MemoryOrderSequentiallyConsistent; | 
| 200 | 211 | 
| 201   return ConstantInt::get(Type::getInt32Ty(C), AO); | 212   return ConstantInt::get(Type::getInt32Ty(C), AO); | 
| 202 } | 213 } | 
| 203 | 214 | 
| 204 std::pair<ConstantInt *, ConstantInt *> | 215 std::pair<ConstantInt *, ConstantInt *> | 
| 205 AtomicVisitor::freezeMemoryOrder(const AtomicCmpXchgInst &I, AtomicOrdering S, | 216 AtomicVisitor::freezeMemoryOrder(const AtomicCmpXchgInst &I, AtomicOrdering S, | 
| 206                                  AtomicOrdering F) const { | 217                                  AtomicOrdering F) const { | 
| 207   if (S == Release || (S == AcquireRelease && F != Acquire)) | 218   if (S == Release || (S == AcquireRelease && F != Acquire)) | 
| 208     // According to C++11's [atomics.types.operations.req], cmpxchg with release | 219     // According to C++11's [atomics.types.operations.req], cmpxchg with release | 
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 416                                         ArrayRef<Value *>()); | 427                                         ArrayRef<Value *>()); | 
| 417   } else { | 428   } else { | 
| 418     const NaCl::AtomicIntrinsics::AtomicIntrinsic *Intrinsic = | 429     const NaCl::AtomicIntrinsics::AtomicIntrinsic *Intrinsic = | 
| 419         findAtomicIntrinsic(I, Intrinsic::nacl_atomic_fence, T); | 430         findAtomicIntrinsic(I, Intrinsic::nacl_atomic_fence, T); | 
| 420     Value *Args[] = {freezeMemoryOrder(I, I.getOrdering())}; | 431     Value *Args[] = {freezeMemoryOrder(I, I.getOrdering())}; | 
| 421     replaceInstructionWithIntrinsicCall(I, Intrinsic, T, T, Args); | 432     replaceInstructionWithIntrinsicCall(I, Intrinsic, T, T, Args); | 
| 422   } | 433   } | 
| 423 } | 434 } | 
| 424 | 435 | 
| 425 ModulePass *llvm::createRewriteAtomicsPass() { return new RewriteAtomics(); } | 436 ModulePass *llvm::createRewriteAtomicsPass() { return new RewriteAtomics(); } | 
| OLD | NEW | 
|---|