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

Unified Diff: lib/Transforms/NaCl/RewriteAtomics.cpp

Issue 22474008: Add the new @llvm.nacl.atomic.fence.all intrinsic (Closed) Base URL: http://git.chromium.org/native_client/pnacl-llvm.git@master
Patch Set: Add note suggested by jvoung. Created 7 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/Transforms/NaCl/RewriteAsmDirectives.cpp ('k') | test/NaCl/PNaClABI/intrinsics.ll » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/Transforms/NaCl/RewriteAtomics.cpp
diff --git a/lib/Transforms/NaCl/RewriteAtomics.cpp b/lib/Transforms/NaCl/RewriteAtomics.cpp
index 26c834a87432b61e152b135c035ba3422c71a4f9..e22e9fdac95c2612ce4ee8a60ce65567fe2c17f3 100644
--- a/lib/Transforms/NaCl/RewriteAtomics.cpp
+++ b/lib/Transforms/NaCl/RewriteAtomics.cpp
@@ -18,6 +18,7 @@
#include "llvm/ADT/Twine.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
@@ -241,9 +242,9 @@ void AtomicVisitor::replaceInstructionWithIntrinsicCall(
ModifiedModule = true;
}
-/// %res = load {atomic|volatile} T* %ptr memory_order, align sizeof(T)
+/// %res = load {atomic|volatile} T* %ptr memory_order, align sizeof(T)
/// becomes:
-/// %res = call T @llvm.nacl.atomic.load.i<size>(%ptr, memory_order)
+/// %res = call T @llvm.nacl.atomic.load.i<size>(%ptr, memory_order)
void AtomicVisitor::visitLoadInst(LoadInst &I) {
if (I.isSimple())
return;
@@ -254,9 +255,9 @@ void AtomicVisitor::visitLoadInst(LoadInst &I) {
PH.OriginalPET, PH.PET, Args);
}
-/// store {atomic|volatile} T %val, T* %ptr memory_order, align sizeof(T)
+/// store {atomic|volatile} T %val, T* %ptr memory_order, align sizeof(T)
/// becomes:
-/// call void @llvm.nacl.atomic.store.i<size>(%val, %ptr, memory_order)
+/// call void @llvm.nacl.atomic.store.i<size>(%val, %ptr, memory_order)
void AtomicVisitor::visitStoreInst(StoreInst &I) {
if (I.isSimple())
return;
@@ -278,9 +279,9 @@ void AtomicVisitor::visitStoreInst(StoreInst &I) {
PH.OriginalPET, PH.PET, Args);
}
-/// %res = atomicrmw OP T* %ptr, T %val memory_order
+/// %res = atomicrmw OP T* %ptr, T %val memory_order
/// becomes:
-/// %res = call T @llvm.nacl.atomic.rmw.i<size>(OP, %ptr, %val, memory_order)
+/// %res = call T @llvm.nacl.atomic.rmw.i<size>(OP, %ptr, %val, memory_order)
void AtomicVisitor::visitAtomicRMWInst(AtomicRMWInst &I) {
NaCl::AtomicRMWOperation Op;
switch (I.getOperation()) {
@@ -300,11 +301,11 @@ void AtomicVisitor::visitAtomicRMWInst(AtomicRMWInst &I) {
PH.OriginalPET, PH.PET, Args);
}
-/// %res = cmpxchg T* %ptr, T %old, T %new memory_order
+/// %res = cmpxchg T* %ptr, T %old, T %new memory_order
/// becomes:
-/// %res = call T @llvm.nacl.atomic.cmpxchg.i<size>(
-/// %object, %expected, %desired, memory_order_success,
-/// memory_order_failure)
+/// %res = call T @llvm.nacl.atomic.cmpxchg.i<size>(
+/// %object, %expected, %desired, memory_order_success,
+/// memory_order_failure)
void AtomicVisitor::visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) {
PointerHelper<AtomicCmpXchgInst> PH(*this, I);
checkSizeMatchesType(I, PH.BitSize, I.getCompareOperand()->getType());
@@ -319,14 +320,38 @@ void AtomicVisitor::visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) {
PH.OriginalPET, PH.PET, Args);
}
-/// fence memory_order
+/// fence memory_order
/// becomes:
-/// call void @llvm.nacl.atomic.fence(memory_order)
+/// call void @llvm.nacl.atomic.fence(memory_order)
+/// and
+/// call void asm sideeffect "", "~{memory}"()
+/// fence seq_cst
+/// call void asm sideeffect "", "~{memory}"()
+/// becomes:
+/// call void asm sideeffect "", "~{memory}"()
+/// call void @llvm.nacl.atomic.fence.all()
+/// call void asm sideeffect "", "~{memory}"()
+/// Note that the assembly gets eliminated by the -remove-asm-memory pass.
void AtomicVisitor::visitFenceInst(FenceInst &I) {
Type *T = Type::getInt32Ty(C); // Fences aren't overloaded on type.
- Value *Args[] = { freezeMemoryOrder(I) };
- replaceInstructionWithIntrinsicCall(I, Intrinsic::nacl_atomic_fence, T, T,
- Args);
+ BasicBlock::InstListType &IL(I.getParent()->getInstList());
+ bool isFirst = IL.empty() || &*I.getParent()->getInstList().begin() == &I;
+ bool isLast = IL.empty() || &*I.getParent()->getInstList().rbegin() == &I;
+ CallInst *PrevC = isFirst ? 0 : dyn_cast<CallInst>(I.getPrevNode());
+ CallInst *NextC = isLast ? 0 : dyn_cast<CallInst>(I.getNextNode());
+
+ if ((PrevC && PrevC->isInlineAsm() &&
+ cast<InlineAsm>(PrevC->getCalledValue())->isAsmMemory()) &&
+ (NextC && NextC->isInlineAsm() &&
+ cast<InlineAsm>(NextC->getCalledValue())->isAsmMemory()) &&
+ I.getOrdering() == SequentiallyConsistent) {
+ replaceInstructionWithIntrinsicCall(I, Intrinsic::nacl_atomic_fence_all, T,
+ T, ArrayRef<Value *>());
+ } else {
+ Value *Args[] = { freezeMemoryOrder(I) };
+ replaceInstructionWithIntrinsicCall(I, Intrinsic::nacl_atomic_fence, T, T,
+ Args);
+ }
}
ModulePass *llvm::createRewriteAtomicsPass() { return new RewriteAtomics(); }
« no previous file with comments | « lib/Transforms/NaCl/RewriteAsmDirectives.cpp ('k') | test/NaCl/PNaClABI/intrinsics.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698