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

Side by Side Diff: lib/Transforms/NaCl/GlobalizeConstantVectors.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
« no previous file with comments | « lib/Transforms/NaCl/GlobalCleanup.cpp ('k') | lib/Transforms/NaCl/InsertDivideCheck.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 //===- GlobalizeConstantVectors.cpp - Globalize constant vector -----------===//
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 all constant vector operands by loads of the same
11 // vector value from a constant global. After this pass functions don't
12 // rely on ConstantVector and ConstantDataVector.
13 //
14 // The FlattenGlobals pass can be used to further simplify the globals
15 // that this pass creates.
16 //
17 //===----------------------------------------------------------------------===//
18
19 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/ADT/SmallPtrSet.h"
21 #include "llvm/IR/Constants.h"
22 #include "llvm/IR/DataLayout.h"
23 #include "llvm/IR/InstIterator.h"
24 #include "llvm/IR/Instructions.h"
25 #include "llvm/IR/Module.h"
26 #include "llvm/Pass.h"
27 #include "llvm/Transforms/NaCl.h"
28 #include <utility>
29 #include <vector>
30
31 using namespace llvm;
32
33 namespace {
34 // Must be a ModulePass since it adds globals.
35 class GlobalizeConstantVectors : public ModulePass {
36 public:
37 static char ID; // Pass identification, replacement for typeid
38 GlobalizeConstantVectors() : ModulePass(ID), DL(0) {
39 initializeGlobalizeConstantVectorsPass(*PassRegistry::getPassRegistry());
40 }
41 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
42 AU.setPreservesCFG();
43 AU.addRequired<DataLayoutPass>();
44 }
45 virtual bool runOnModule(Module &M);
46
47 private:
48 typedef SmallPtrSet<Constant *, 64> Constants;
49 typedef std::pair<Function *, Constants> FunctionConstants;
50 typedef std::vector<FunctionConstants> FunctionConstantList;
51 typedef DenseMap<Constant *, GlobalVariable *> GlobalizedConstants;
52 const DataLayout *DL;
53
54 void findConstantVectors(const Function &F, Constants &Cs) const;
55 void createGlobalConstantVectors(Module &M, const FunctionConstantList &FCs,
56 GlobalizedConstants &GCs) const;
57 void materializeConstantVectors(Function &F, const Constants &Cs,
58 const GlobalizedConstants &GCs) const;
59 };
60
61 const char Name[] = "constant_vector";
62 } // anonymous namespace
63
64 char GlobalizeConstantVectors::ID = 0;
65 INITIALIZE_PASS(GlobalizeConstantVectors, "globalize-constant-vectors",
66 "Replace constant vector operands with equivalent loads", false,
67 false)
68
69 void GlobalizeConstantVectors::findConstantVectors(const Function &F,
70 Constants &Cs) const {
71 for (const_inst_iterator II = inst_begin(F), IE = inst_end(F); II != IE;
72 ++II) {
73 for (User::const_op_iterator OI = II->op_begin(), OE = II->op_end();
74 OI != OE; ++OI) {
75 Value *V = OI->get();
76 if (isa<ConstantVector>(V) || isa<ConstantDataVector>(V) ||
77 isa<ConstantAggregateZero>(V))
78 Cs.insert(cast<Constant>(V));
79 }
80 }
81 }
82
83 void GlobalizeConstantVectors::createGlobalConstantVectors(
84 Module &M, const FunctionConstantList &FCs,
85 GlobalizedConstants &GCs) const {
86 for (FunctionConstantList::const_iterator FCI = FCs.begin(), FCE = FCs.end();
87 FCI != FCE; ++FCI) {
88 const Constants &Cs = FCI->second;
89
90 for (Constants::const_iterator CI = Cs.begin(), CE = Cs.end(); CI != CE;
91 ++CI) {
92 Constant *C = *CI;
93 if (GCs.find(C) != GCs.end())
94 continue; // The vector has already been globalized.
95 GlobalVariable *GV =
96 new GlobalVariable(M, C->getType(), /* isConstant= */ true,
97 GlobalValue::InternalLinkage, C, Name);
98 GV->setAlignment(DL->getPrefTypeAlignment(C->getType()));
99 GV->setUnnamedAddr(true); // The content is significant, not the address.
100 GCs[C] = GV;
101 }
102 }
103 }
104
105 void GlobalizeConstantVectors::materializeConstantVectors(
106 Function &F, const Constants &Cs, const GlobalizedConstants &GCs) const {
107 // The first instruction in a function dominates all others, it is therefore a
108 // safe insertion point.
109 Instruction *FirstInst = F.getEntryBlock().getFirstNonPHI();
110
111 for (Constants::const_iterator CI = Cs.begin(), CE = Cs.end(); CI != CE;
112 ++CI) {
113 Constant *C = *CI;
114 GlobalizedConstants::const_iterator GVI = GCs.find(C);
115 assert(GVI != GCs.end());
116 GlobalVariable *GV = GVI->second;
117 LoadInst *MaterializedGV = new LoadInst(GV, Name, /* isVolatile= */ false,
118 GV->getAlignment(), FirstInst);
119
120 // Find users of the constant vector.
121 typedef SmallVector<User *, 64> UserList;
122 UserList CVUsers;
123 for (auto U : C->users()) {
124 if (Instruction *I = dyn_cast<Instruction>(U))
125 if (I->getParent()->getParent() != &F)
126 // Skip uses of the constant vector in other functions: we need to
127 // materialize it in every function which has a use.
128 continue;
129 if (isa<Constant>(U))
130 // Don't replace global uses of the constant vector: we just created a
131 // new one. This avoid recursive references.
132 // Also, it's not legal to replace a constant's operand with
133 // a non-constant (the load instruction).
134 continue;
135 CVUsers.push_back(U);
136 }
137
138 // Replace these Users. Must be done separately to avoid invalidating the
139 // User iterator.
140 for (UserList::iterator UI = CVUsers.begin(), UE = CVUsers.end(); UI != UE;
141 ++UI) {
142 User *U = *UI;
143 for (User::op_iterator OI = U->op_begin(), OE = U->op_end(); OI != OE;
144 ++OI)
145 if (dyn_cast<Constant>(*OI) == C)
146 // The current operand is a use of the constant vector, replace it
147 // with the materialized one.
148 *OI = MaterializedGV;
149 }
150 }
151 }
152
153 bool GlobalizeConstantVectors::runOnModule(Module &M) {
154 DL = &getAnalysis<DataLayoutPass>().getDataLayout();
155
156 FunctionConstantList FCs;
157 FCs.reserve(M.size());
158 for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) {
159 Constants Cs;
160 findConstantVectors(*FI, Cs);
161 if (!Cs.empty())
162 FCs.push_back(std::make_pair(&*FI, Cs));
163 }
164
165 GlobalizedConstants GCs;
166 createGlobalConstantVectors(M, FCs, GCs);
167
168 for (FunctionConstantList::const_iterator FCI = FCs.begin(), FCE = FCs.end();
169 FCI != FCE; ++FCI)
170 materializeConstantVectors(*FCI->first, FCI->second, GCs);
171
172 return FCs.empty();
173 }
174
175 ModulePass *llvm::createGlobalizeConstantVectorsPass() {
176 return new GlobalizeConstantVectors();
177 }
OLDNEW
« no previous file with comments | « lib/Transforms/NaCl/GlobalCleanup.cpp ('k') | lib/Transforms/NaCl/InsertDivideCheck.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698