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

Side by Side Diff: lib/Transforms/NaCl/RewriteLLVMIntrinsics.cpp

Issue 939073008: Rebased PNaCl localmods in LLVM to 223109 (Closed)
Patch Set: undo localmod Created 5 years, 9 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
OLDNEW
(Empty)
1 //===- RewriteLLVMIntrinsics.cpp - Rewrite LLVM intrinsics to other values ===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This pass replaces calls to LLVM intrinsics that are *not* part of the
11 // PNaCl stable bitcode ABI into simpler values.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/ADT/Twine.h"
16 #include "llvm/IR/Constants.h"
17 #include "llvm/IR/Instructions.h"
18 #include "llvm/IR/Intrinsics.h"
19 #include "llvm/IR/Module.h"
20 #include "llvm/Pass.h"
21 #include "llvm/Support/raw_ostream.h"
22 #include "llvm/Transforms/NaCl.h"
23 #include <string>
24
25 using namespace llvm;
26
27 namespace {
28 class RewriteLLVMIntrinsics : public ModulePass {
29 public:
30 static char ID;
31 RewriteLLVMIntrinsics() : ModulePass(ID) {
32 // This is a module pass because this makes it easier to access uses
33 // of global intrinsic functions.
34 initializeRewriteLLVMIntrinsicsPass(*PassRegistry::getPassRegistry());
35 }
36
37 virtual bool runOnModule(Module &M);
38
39 /// Rewrite an intrinsic to something different.
40 class IntrinsicRewriter {
41 public:
42 Function *function() const { return F; }
43 /// Called once per \p Call of the Intrinsic Function.
44 void rewriteCall(CallInst *Call) { doRewriteCall(Call); }
45
46 protected:
47 IntrinsicRewriter(Module &M, Intrinsic::ID IntrinsicID)
48 : F(Intrinsic::getDeclaration(&M, IntrinsicID)) {}
49 virtual ~IntrinsicRewriter() {}
50 /// This pure virtual method must be defined by implementors, and
51 /// will be called by rewriteCall.
52 virtual void doRewriteCall(CallInst *Call) = 0;
53
54 Function *F;
55
56 private:
57 IntrinsicRewriter() LLVM_DELETED_FUNCTION;
58 IntrinsicRewriter(const IntrinsicRewriter &) LLVM_DELETED_FUNCTION;
59 IntrinsicRewriter &operator=(
60 const IntrinsicRewriter &) LLVM_DELETED_FUNCTION;
61 };
62
63 private:
64 /// Visit all uses of a Function, rewrite it using the \p Rewriter,
65 /// and then delete the Call. Later delete the Function from the
66 /// Module. Returns true if the Module was changed.
67 bool visitUses(IntrinsicRewriter &Rewriter);
68 };
69
70 /// Rewrite a Call to nothing.
71 class ToNothing : public RewriteLLVMIntrinsics::IntrinsicRewriter {
72 public:
73 ToNothing(Module &M, Intrinsic::ID IntrinsicID)
74 : IntrinsicRewriter(M, IntrinsicID) {}
75 virtual ~ToNothing() {}
76
77 protected:
78 virtual void doRewriteCall(CallInst *Call) {
79 // Nothing to do: the visit does the deletion.
80 }
81 };
82
83 /// Rewrite a Call to a ConstantInt of the same type.
84 class ToConstantInt : public RewriteLLVMIntrinsics::IntrinsicRewriter {
85 public:
86 ToConstantInt(Module &M, Intrinsic::ID IntrinsicID, uint64_t Value)
87 : IntrinsicRewriter(M, IntrinsicID), Value(Value),
88 RetType(function()->getFunctionType()->getReturnType()) {}
89 virtual ~ToConstantInt() {}
90
91 protected:
92 virtual void doRewriteCall(CallInst *Call) {
93 Constant *C = ConstantInt::get(RetType, Value);
94 Call->replaceAllUsesWith(C);
95 }
96
97 private:
98 uint64_t Value;
99 Type *RetType;
100 };
101 }
102
103 char RewriteLLVMIntrinsics::ID = 0;
104 INITIALIZE_PASS(RewriteLLVMIntrinsics, "rewrite-llvm-intrinsic-calls",
105 "Rewrite LLVM intrinsic calls to simpler expressions", false,
106 false)
107
108 bool RewriteLLVMIntrinsics::runOnModule(Module &M) {
109 // Replace all uses of the @llvm.flt.rounds intrinsic with the constant
110 // "1" (round-to-nearest). Until we add a second intrinsic like
111 // @llvm.set.flt.round it is impossible to have a rounding mode that is
112 // not the initial rounding mode (round-to-nearest). We can remove
113 // this rewrite after adding a set() intrinsic.
114 ToConstantInt FltRoundsRewriter(M, Intrinsic::flt_rounds, 1);
115
116 // Remove all @llvm.prefetch intrinsics.
117 ToNothing PrefetchRewriter(M, Intrinsic::prefetch);
118
119 return visitUses(FltRoundsRewriter) | visitUses(PrefetchRewriter);
120 }
121
122 bool RewriteLLVMIntrinsics::visitUses(IntrinsicRewriter &Rewriter) {
123 Function *F = Rewriter.function();
124 SmallVector<CallInst *, 64> Calls;
125 for (User *U : F->users()) {
126 if (CallInst *Call = dyn_cast<CallInst>(U)) {
127 Calls.push_back(Call);
128 } else {
129 // Intrinsics we care about currently don't need to handle this case.
130 std::string S;
131 raw_string_ostream OS(S);
132 OS << "Taking the address of this intrinsic is invalid: " << *U;
133 report_fatal_error(OS.str());
134 }
135 }
136
137 for (auto Call : Calls) {
138 Rewriter.rewriteCall(Call);
139 Call->eraseFromParent();
140 }
141
142 F->eraseFromParent();
143 return !Calls.empty();
144 }
145
146 ModulePass *llvm::createRewriteLLVMIntrinsicsPass() {
147 return new RewriteLLVMIntrinsics();
148 }
OLDNEW
« no previous file with comments | « lib/Transforms/NaCl/RewriteAtomics.cpp ('k') | lib/Transforms/NaCl/RewritePNaClLibraryCalls.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698