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

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

Issue 927493002: PNaCl: Impl the other atomicrmw operations: nand, max, min, umax, and umin. Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Reduce big-O cost. Created 5 years, 5 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/LLVMBuild.txt ('k') | test/Transforms/NaCl/atomic/extra-rmw-operations.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 652635ab0a2c85028e055476f90f6fa231af639a..858a4d7ca861d1ee0bbe3d0918cd9c18cf752d12 100644
--- a/lib/Transforms/NaCl/RewriteAtomics.cpp
+++ b/lib/Transforms/NaCl/RewriteAtomics.cpp
@@ -15,6 +15,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
@@ -28,6 +29,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/TargetRegistry.h"
#include "llvm/Transforms/NaCl.h"
#include <climits>
#include <string>
@@ -75,6 +77,8 @@ public:
void visitAtomicRMWInst(AtomicRMWInst &I);
void visitFenceInst(FenceInst &I);
+ SmallVectorImpl<Function*>& getFunsWithExtraRMWOps() { return FunsWithExtraRMWOps; }
+
private:
Module &M;
LLVMContext &C;
@@ -82,6 +86,13 @@ private:
NaCl::AtomicIntrinsics AI;
bool ModifiedModule;
+ /// These functions have atomic instructions which we expand with
+ /// -atomic-expand. We collect them here so we don't have to check every
+ /// instruction of every basicblock of every function in the module twice over
+ /// the coarse of the pass (under the assumption that atomic operations are
+ /// the expection rather than the rule).
JF 2015/07/23 22:44:38 "exception"
+ SmallVector<Function*, 32> FunsWithExtraRMWOps;
+
AtomicVisitor() = delete;
AtomicVisitor(const AtomicVisitor &) = delete;
AtomicVisitor &operator=(const AtomicVisitor &) = delete;
@@ -162,9 +173,53 @@ INITIALIZE_PASS(RewriteAtomics, "nacl-rewrite-atomics",
false, false)
bool RewriteAtomics::runOnModule(Module &M) {
+ // rewrite nand, (u)max, (u)min rmw atomics:
+ // First we need a target machine to appease its lordship:
+
+ // Get the target specific parser.
+ std::string Error;
+ Triple TheTriple = Triple("i686-none-nacl");
+ const Target *TheTarget = TargetRegistry::lookupTarget("", TheTriple,
+ Error);
+ if (!TheTarget) {
+ errs() << "Looking up 'i686-none-nacl':" << ": " << Error;
+ report_fatal_error("Did you forget to initialize the x86 target?");
+ }
+
+ // Create the target machine:
+ std::unique_ptr<TargetMachine> Target(
+ TheTarget->createTargetMachine(TheTriple.getTriple(), "generic", "",
+ TargetOptions(), Reloc::Default,
+ CodeModel::Default, CodeGenOpt::Default));
+ assert(Target != nullptr);
+
+ std::unique_ptr<FunctionPass> AtomicRMWExpander
+ (createAtomicExpandPass(Target.get()));
+
+
AtomicVisitor AV(M, *this);
AV.visit(M);
- return AV.modifiedModule();
+
+ bool Changed = AV.modifiedModule();
+
+ // Expand any leftover RMW atomics:
+ // This is done after because otherwise -atomic-expand will expand stuff we're
+ // capable of expanding, leaving us with less efficient code.
+ const size_t PrevLen = AV.getFunsWithExtraRMWOps().size();
+ for(auto *F : AV.getFunsWithExtraRMWOps()) {
+ const bool Expanded = AtomicRMWExpander->runOnFunction(*F);
+ (void)Expanded;
+ assert(Expanded);
+ // revisit the function, rewriting cmpxchg to the corresponding
+ // llvm.nacl.etc.etc.
+ AV.visit(*F);
+ Changed = true;
+ }
+ // assert that -atomic-expand didn't leave things we can't expand.
+ (void)PrevLen;
+ assert(PrevLen == AV.getFunsWithExtraRMWOps().size());
+
+ return Changed;
}
template <class Instruction>
@@ -347,7 +402,11 @@ void AtomicVisitor::visitStoreInst(StoreInst &I) {
void AtomicVisitor::visitAtomicRMWInst(AtomicRMWInst &I) {
NaCl::AtomicRMWOperation Op;
switch (I.getOperation()) {
- default: report_fatal_error("unsupported atomicrmw operation: " + ToStr(I));
+ default: {
+ // delegate to -atomic-expand
+ FunsWithExtraRMWOps.push_back(I.getParent()->getParent());
+ return;
+ }
case AtomicRMWInst::Add: Op = NaCl::AtomicAdd; break;
case AtomicRMWInst::Sub: Op = NaCl::AtomicSub; break;
case AtomicRMWInst::And: Op = NaCl::AtomicAnd; break;
« no previous file with comments | « lib/Transforms/NaCl/LLVMBuild.txt ('k') | test/Transforms/NaCl/atomic/extra-rmw-operations.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698