| 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 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 class RewriteAtomics : public ModulePass { | 44 class RewriteAtomics : public ModulePass { |
| 45 public: | 45 public: |
| 46 static char ID; // Pass identification, replacement for typeid | 46 static char ID; // Pass identification, replacement for typeid |
| 47 RewriteAtomics() : ModulePass(ID) { | 47 RewriteAtomics() : ModulePass(ID) { |
| 48 // This is a module pass because it may have to introduce | 48 // This is a module pass because it may have to introduce |
| 49 // intrinsic declarations into the module and modify a global function. | 49 // intrinsic declarations into the module and modify a global function. |
| 50 initializeRewriteAtomicsPass(*PassRegistry::getPassRegistry()); | 50 initializeRewriteAtomicsPass(*PassRegistry::getPassRegistry()); |
| 51 } | 51 } |
| 52 | 52 |
| 53 virtual bool runOnModule(Module &M); | 53 virtual bool runOnModule(Module &M); |
| 54 virtual void getAnalysisUsage(AnalysisUsage &Info) const { | |
| 55 Info.addRequired<DataLayoutPass>(); | |
| 56 } | |
| 57 }; | 54 }; |
| 58 | 55 |
| 59 template <class T> std::string ToStr(const T &V) { | 56 template <class T> std::string ToStr(const T &V) { |
| 60 std::string S; | 57 std::string S; |
| 61 raw_string_ostream OS(S); | 58 raw_string_ostream OS(S); |
| 62 OS << const_cast<T &>(V); | 59 OS << const_cast<T &>(V); |
| 63 return OS.str(); | 60 return OS.str(); |
| 64 } | 61 } |
| 65 | 62 |
| 66 class AtomicVisitor : public InstVisitor<AtomicVisitor> { | 63 class AtomicVisitor : public InstVisitor<AtomicVisitor> { |
| 67 public: | 64 public: |
| 68 AtomicVisitor(Module &M, Pass &P) | 65 AtomicVisitor(Module &M, Pass &P) |
| 69 : M(M), C(M.getContext()), | 66 : M(M), C(M.getContext()), |
| 70 TD(P.getAnalysis<DataLayoutPass>().getDataLayout()), AI(C), | 67 TD(M.getDataLayout()), AI(C), |
| 71 ModifiedModule(false) {} | 68 ModifiedModule(false) {} |
| 72 ~AtomicVisitor() {} | 69 ~AtomicVisitor() {} |
| 73 bool modifiedModule() const { return ModifiedModule; } | 70 bool modifiedModule() const { return ModifiedModule; } |
| 74 | 71 |
| 75 void visitLoadInst(LoadInst &I); | 72 void visitLoadInst(LoadInst &I); |
| 76 void visitStoreInst(StoreInst &I); | 73 void visitStoreInst(StoreInst &I); |
| 77 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &I); | 74 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &I); |
| 78 void visitAtomicRMWInst(AtomicRMWInst &I); | 75 void visitAtomicRMWInst(AtomicRMWInst &I); |
| 79 void visitFenceInst(FenceInst &I); | 76 void visitFenceInst(FenceInst &I); |
| 80 | 77 |
| 81 private: | 78 private: |
| 82 Module &M; | 79 Module &M; |
| 83 LLVMContext &C; | 80 LLVMContext &C; |
| 84 const DataLayout TD; | 81 const DataLayout TD; |
| 85 NaCl::AtomicIntrinsics AI; | 82 NaCl::AtomicIntrinsics AI; |
| 86 bool ModifiedModule; | 83 bool ModifiedModule; |
| 87 | 84 |
| 88 AtomicVisitor() LLVM_DELETED_FUNCTION; | 85 AtomicVisitor() = delete; |
| 89 AtomicVisitor(const AtomicVisitor &) LLVM_DELETED_FUNCTION; | 86 AtomicVisitor(const AtomicVisitor &) = delete; |
| 90 AtomicVisitor &operator=(const AtomicVisitor &) LLVM_DELETED_FUNCTION; | 87 AtomicVisitor &operator=(const AtomicVisitor &) = delete; |
| 91 | 88 |
| 92 /// Create an integer constant holding a NaCl::MemoryOrder that can be | 89 /// Create an integer constant holding a NaCl::MemoryOrder that can be |
| 93 /// passed as an argument to one of the @llvm.nacl.atomic.* | 90 /// passed as an argument to one of the @llvm.nacl.atomic.* |
| 94 /// intrinsics. This function may strengthen the ordering initially | 91 /// intrinsics. This function may strengthen the ordering initially |
| 95 /// specified by the instruction \p I for stability purpose. | 92 /// specified by the instruction \p I for stability purpose. |
| 96 template <class Instruction> | 93 template <class Instruction> |
| 97 ConstantInt *freezeMemoryOrder(const Instruction &I, AtomicOrdering O) const; | 94 ConstantInt *freezeMemoryOrder(const Instruction &I, AtomicOrdering O) const; |
| 98 std::pair<ConstantInt *, ConstantInt *> | 95 std::pair<ConstantInt *, ConstantInt *> |
| 99 freezeMemoryOrder(const AtomicCmpXchgInst &I, AtomicOrdering S, | 96 freezeMemoryOrder(const AtomicCmpXchgInst &I, AtomicOrdering S, |
| 100 AtomicOrdering F) const; | 97 AtomicOrdering F) const; |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 ArrayRef<Value *>()); | 420 ArrayRef<Value *>()); |
| 424 } else { | 421 } else { |
| 425 const NaCl::AtomicIntrinsics::AtomicIntrinsic *Intrinsic = | 422 const NaCl::AtomicIntrinsics::AtomicIntrinsic *Intrinsic = |
| 426 findAtomicIntrinsic(I, Intrinsic::nacl_atomic_fence, T); | 423 findAtomicIntrinsic(I, Intrinsic::nacl_atomic_fence, T); |
| 427 Value *Args[] = {freezeMemoryOrder(I, I.getOrdering())}; | 424 Value *Args[] = {freezeMemoryOrder(I, I.getOrdering())}; |
| 428 replaceInstructionWithIntrinsicCall(I, Intrinsic, T, T, Args); | 425 replaceInstructionWithIntrinsicCall(I, Intrinsic, T, T, Args); |
| 429 } | 426 } |
| 430 } | 427 } |
| 431 | 428 |
| 432 ModulePass *llvm::createRewriteAtomicsPass() { return new RewriteAtomics(); } | 429 ModulePass *llvm::createRewriteAtomicsPass() { return new RewriteAtomics(); } |
| OLD | NEW |