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

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

Issue 221693002: PNaCl: Add support for GCC/LLVM vector extensions (Closed) Base URL: http://git.chromium.org/native_client/pnacl-llvm.git@master
Patch Set: Address dschuff's comments. Created 6 years, 8 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 //===- 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.
jvoung (off chromium) 2014/04/16 00:10:27 Maybe reference the FlattenGlobals pass too -- It
JF 2014/04/16 20:48:07 Done.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "llvm/IR/Constants.h"
17 #include "llvm/IR/DataLayout.h"
18 #include "llvm/IR/Instructions.h"
19 #include "llvm/IR/Module.h"
20 #include "llvm/Pass.h"
21 #include "llvm/Support/InstIterator.h"
22 #include "llvm/Transforms/NaCl.h"
23
24 using namespace llvm;
25
26 namespace {
27 // Must be a ModulePass since it adds globals.
28 class GlobalizeConstantVectors : public ModulePass {
29 public:
30 static char ID; // Pass identification, replacement for typeid
31 GlobalizeConstantVectors() : ModulePass(ID), DL(0) {
32 initializeGlobalizeConstantVectorsPass(*PassRegistry::getPassRegistry());
33 }
34 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
35 AU.setPreservesCFG();
36 AU.addRequired<DataLayout>();
37 }
38 virtual bool runOnModule(Module &M);
39
40 private:
41 typedef SmallVector<Value *, 128> Values;
42 const DataLayout *DL;
43
44 void findConstantVectors(const Function &F, Values &CVs) const;
45 void globalizeConstantVectors(Module &M, Function &F,
46 const Values &CVs) const;
47 };
48 } // anonymous namespace
49
50 char GlobalizeConstantVectors::ID = 0;
51 INITIALIZE_PASS(GlobalizeConstantVectors, "globalize-constant-vectors",
52 "Replace constant vector operands with equivalent loads", false,
53 false)
54
55 void GlobalizeConstantVectors::findConstantVectors(const Function &F,
56 Values &CVs) const {
57 for (const_inst_iterator II = inst_begin(F), IE = inst_end(F); II != IE;
58 ++II) {
59 for (User::const_op_iterator OI = II->op_begin(), OE = II->op_end();
60 OI != OE; ++OI) {
61 Value *V = OI->get();
62 if (isa<ConstantVector>(V) || isa<ConstantDataVector>(V))
63 CVs.push_back(V);
64 }
65 }
66 }
67
68 void
69 GlobalizeConstantVectors::globalizeConstantVectors(Module &M, Function &F,
70 const Values &CVs) const {
71 // The first instruction in a function dominates all others, it is
72 // therefore a safe insertion point.
73 // TODO(jfb) Sink values closer to their use?
74 Instruction *FirstInst = F.getEntryBlock().getFirstNonPHI();
75 for (Values::const_iterator VI = CVs.begin(), VE = CVs.end(); VI != VE;
76 ++VI) {
77 Value *V = *VI;
78 static const char Name[] = "constant_vector";
79
80 GlobalVariable *GV = new GlobalVariable(
81 M, V->getType(), /* isConstant= */ true, GlobalValue::InternalLinkage,
82 cast<Constant>(V), Name);
83 GV->setAlignment(DL->getPrefTypeAlignment(V->getType()));
84 LoadInst *MaterializedGV = new LoadInst(GV, Name, /* isVolatile= */ false,
85 GV->getAlignment(), FirstInst);
86
87 for (Value::use_iterator UI = V->use_begin(), UE = V->use_end(); UI != UE;
88 ++UI) {
89 User *U = *UI;
90 if (Instruction *I = dyn_cast<Instruction>(U))
91 if (I->getParent()->getParent() != &F)
92 // Skip uses of the constant vector in other functions: we
93 // need to materialize it in every function which has a use.
94 continue;
95 if (isa<GlobalVariable>(U))
96 // Don't replace global uses of the constant vector: we just
97 // created a new one. This avoid recursive references.
98 continue;
99 for (User::op_iterator OI = U->op_begin(), OE = U->op_end(); OI != OE;
100 ++OI)
101 if (dyn_cast<Value>(*OI) == V)
102 // The current operand is a use of the constant vector,
103 // replace it with the materialized one.
104 *OI = MaterializedGV;
105 }
106 }
107 }
108
109 bool GlobalizeConstantVectors::runOnModule(Module &M) {
110 bool Changed = false;
111 DL = &getAnalysis<DataLayout>();
112 for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) {
113 Function &F = *FI;
114 Values ConstantVectors;
115 findConstantVectors(F, ConstantVectors);
116 if (!ConstantVectors.empty()) {
117 Changed = true;
118 globalizeConstantVectors(M, F, ConstantVectors);
119 }
120 }
121 return Changed;
122 }
123
124 ModulePass *llvm::createGlobalizeConstantVectorsPass() {
125 return new GlobalizeConstantVectors();
126 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698