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

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

Issue 1151093004: Changes from 3.7 merge to files not in upstream (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Created 5 years, 7 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
1 //===- ExpandStructRegs.cpp - Expand out variables with struct type--------===// 1 //===- ExpandStructRegs.cpp - Expand out variables with struct type--------===//
2 // 2 //
3 // The LLVM Compiler Infrastructure 3 // The LLVM Compiler Infrastructure
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This pass expands out some uses of LLVM variables 10 // This pass expands out some uses of LLVM variables
(...skipping 25 matching lines...) Expand all
36 // padding fields are not defined anyway. 36 // padding fields are not defined anyway.
37 // 37 //
38 //===----------------------------------------------------------------------===// 38 //===----------------------------------------------------------------------===//
39 39
40 #include "llvm/ADT/SmallVector.h" 40 #include "llvm/ADT/SmallVector.h"
41 #include "llvm/IR/Constants.h" 41 #include "llvm/IR/Constants.h"
42 #include "llvm/IR/DataLayout.h" 42 #include "llvm/IR/DataLayout.h"
43 #include "llvm/IR/Function.h" 43 #include "llvm/IR/Function.h"
44 #include "llvm/IR/Instructions.h" 44 #include "llvm/IR/Instructions.h"
45 #include "llvm/IR/IntrinsicInst.h" 45 #include "llvm/IR/IntrinsicInst.h"
46 #include "llvm/IR/Module.h"
46 #include "llvm/Pass.h" 47 #include "llvm/Pass.h"
47 #include "llvm/Support/Debug.h" 48 #include "llvm/Support/Debug.h"
48 #include "llvm/Support/raw_ostream.h" 49 #include "llvm/Support/raw_ostream.h"
49 #include "llvm/Transforms/NaCl.h" 50 #include "llvm/Transforms/NaCl.h"
50 51
51 #define DEBUG_TYPE "expand-struct-regs" 52 #define DEBUG_TYPE "expand-struct-regs"
52 53
53 using namespace llvm; 54 using namespace llvm;
54 55
55 namespace { 56 namespace {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 Select); 145 Select);
145 } 146 }
146 Select->replaceAllUsesWith(NewStruct); 147 Select->replaceAllUsesWith(NewStruct);
147 Select->eraseFromParent(); 148 Select->eraseFromParent();
148 149
149 return NeedsAnotherPass; 150 return NeedsAnotherPass;
150 } 151 }
151 152
152 template <class InstType> 153 template <class InstType>
153 static void ProcessLoadOrStoreAttrs(InstType *Dest, InstType *Src, 154 static void ProcessLoadOrStoreAttrs(InstType *Dest, InstType *Src,
154 StructType* STy, const unsigned Index) { 155 StructType* STy, const unsigned Index,
156 const DataLayout *DL) {
155 CopyDebug(Dest, Src); 157 CopyDebug(Dest, Src);
156 Dest->setVolatile(Src->isVolatile()); 158 Dest->setVolatile(Src->isVolatile());
157 if (Src->isAtomic()) { 159 if (Src->isAtomic()) {
158 errs() << "Use: " << *Src << "\n"; 160 errs() << "Use: " << *Src << "\n";
159 report_fatal_error("Atomic struct loads/stores not supported"); 161 report_fatal_error("Atomic struct loads/stores not supported");
160 } 162 }
161 163
162 if (!Src->getAlignment()) { 164 if (!Src->getAlignment()) {
163 return; 165 return;
164 } 166 }
165 167
166 const DataLayout *DL = Src->getParent()->getDataLayout();
167 if (!DL) {
168 report_fatal_error("Need DataLayout");
169 }
170 const StructLayout *SL = DL->getStructLayout(STy); 168 const StructLayout *SL = DL->getStructLayout(STy);
171 const unsigned Alignment = Src->getAlignment(); 169 const unsigned Alignment = Src->getAlignment();
172 Dest->setAlignment(MinAlign(Alignment, SL->getElementOffset(Index))); 170 Dest->setAlignment(MinAlign(Alignment, SL->getElementOffset(Index)));
173 } 171 }
174 172
175 static bool SplitUpStore(StoreInst *Store) { 173 static bool SplitUpStore(StoreInst *Store, const DataLayout *DL) {
176 StructType *STy = cast<StructType>(Store->getValueOperand()->getType()); 174 StructType *STy = cast<StructType>(Store->getValueOperand()->getType());
177 175
178 bool NeedsAnotherPass = false; 176 bool NeedsAnotherPass = false;
179 // Create a separate store instruction for each struct field. 177 // Create a separate store instruction for each struct field.
180 for (unsigned Index = 0; Index < STy->getNumElements(); ++Index) { 178 for (unsigned Index = 0; Index < STy->getNumElements(); ++Index) {
181 SmallVector<Value *, 2> Indexes; 179 SmallVector<Value *, 2> Indexes;
182 Indexes.push_back(ConstantInt::get(Store->getContext(), APInt(32, 0))); 180 Indexes.push_back(ConstantInt::get(Store->getContext(), APInt(32, 0)));
183 Indexes.push_back(ConstantInt::get(Store->getContext(), APInt(32, Index))); 181 Indexes.push_back(ConstantInt::get(Store->getContext(), APInt(32, Index)));
184 Value *GEP = 182 Value *GEP =
185 CopyDebug(GetElementPtrInst::Create( 183 CopyDebug(GetElementPtrInst::Create(
184 STy,
186 Store->getPointerOperand(), Indexes, 185 Store->getPointerOperand(), Indexes,
187 Store->getPointerOperand()->getName() + ".index", Store), 186 Store->getPointerOperand()->getName() + ".index", Store),
188 Store); 187 Store);
189 NeedsAnotherPass = 188 NeedsAnotherPass =
190 NeedsAnotherPass || DoAnotherPass(GEP->getType()->getContainedType(0)); 189 NeedsAnotherPass || DoAnotherPass(GEP->getType()->getContainedType(0));
191 190
192 SmallVector<unsigned, 1> EVIndexes; 191 SmallVector<unsigned, 1> EVIndexes;
193 EVIndexes.push_back(Index); 192 EVIndexes.push_back(Index);
194 Value *Field = ExtractValueInst::Create(Store->getValueOperand(), EVIndexes, 193 Value *Field = ExtractValueInst::Create(Store->getValueOperand(), EVIndexes,
195 "", Store); 194 "", Store);
196 StoreInst *NewStore = new StoreInst(Field, GEP, Store); 195 StoreInst *NewStore = new StoreInst(Field, GEP, Store);
197 ProcessLoadOrStoreAttrs(NewStore, Store, STy, Index); 196 ProcessLoadOrStoreAttrs(NewStore, Store, STy, Index, DL);
198 } 197 }
199 Store->eraseFromParent(); 198 Store->eraseFromParent();
200 199
201 return NeedsAnotherPass; 200 return NeedsAnotherPass;
202 } 201 }
203 202
204 static bool SplitUpLoad(LoadInst *Load) { 203 static bool SplitUpLoad(LoadInst *Load, const DataLayout *DL) {
205 StructType *STy = cast<StructType>(Load->getType()); 204 StructType *STy = cast<StructType>(Load->getType());
206 Value *NewStruct = UndefValue::get(STy); 205 Value *NewStruct = UndefValue::get(STy);
207 206
208 bool NeedsAnotherPass = false; 207 bool NeedsAnotherPass = false;
209 // Create a separate load instruction for each struct field. 208 // Create a separate load instruction for each struct field.
210 for (unsigned Index = 0; Index < STy->getNumElements(); ++Index) { 209 for (unsigned Index = 0; Index < STy->getNumElements(); ++Index) {
211 SmallVector<Value *, 2> Indexes; 210 SmallVector<Value *, 2> Indexes;
212 Indexes.push_back(ConstantInt::get(Load->getContext(), APInt(32, 0))); 211 Indexes.push_back(ConstantInt::get(Load->getContext(), APInt(32, 0)));
213 Indexes.push_back(ConstantInt::get(Load->getContext(), APInt(32, Index))); 212 Indexes.push_back(ConstantInt::get(Load->getContext(), APInt(32, Index)));
214 Value *GEP = 213 Value *GEP =
215 CopyDebug(GetElementPtrInst::Create(Load->getPointerOperand(), Indexes, 214 CopyDebug(GetElementPtrInst::Create(STy,
215 Load->getPointerOperand(), Indexes,
216 Load->getName() + ".index", Load), 216 Load->getName() + ".index", Load),
217 Load); 217 Load);
218 LoadInst *NewLoad = new LoadInst(GEP, Load->getName() + ".field", Load); 218 LoadInst *NewLoad = new LoadInst(GEP, Load->getName() + ".field", Load);
219 219
220 NeedsAnotherPass = NeedsAnotherPass || DoAnotherPass(NewLoad); 220 NeedsAnotherPass = NeedsAnotherPass || DoAnotherPass(NewLoad);
221 ProcessLoadOrStoreAttrs(NewLoad, Load, STy, Index); 221 ProcessLoadOrStoreAttrs(NewLoad, Load, STy, Index, DL);
222 222
223 // Reconstruct the struct value. 223 // Reconstruct the struct value.
224 SmallVector<unsigned, 1> EVIndexes; 224 SmallVector<unsigned, 1> EVIndexes;
225 EVIndexes.push_back(Index); 225 EVIndexes.push_back(Index);
226 NewStruct = 226 NewStruct =
227 CopyDebug(InsertValueInst::Create(NewStruct, NewLoad, EVIndexes, 227 CopyDebug(InsertValueInst::Create(NewStruct, NewLoad, EVIndexes,
228 Load->getName() + ".insert", Load), 228 Load->getName() + ".insert", Load),
229 Load); 229 Load);
230 } 230 }
231 Load->replaceAllUsesWith(NewStruct); 231 Load->replaceAllUsesWith(NewStruct);
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 for (Instruction *I : ToErase) { 418 for (Instruction *I : ToErase) {
419 I->eraseFromParent(); 419 I->eraseFromParent();
420 } 420 }
421 421
422 return Changed; 422 return Changed;
423 } 423 }
424 424
425 bool ExpandStructRegs::runOnFunction(Function &Func) { 425 bool ExpandStructRegs::runOnFunction(Function &Func) {
426 bool Changed = false; 426 bool Changed = false;
427 bool NeedsAnotherPass; 427 bool NeedsAnotherPass;
428 const DataLayout *DL = &Func.getParent()->getDataLayout();
428 429
429 do { 430 do {
430 NeedsAnotherPass = false; 431 NeedsAnotherPass = false;
431 // Split up aggregate loads, stores and phi nodes into operations on 432 // Split up aggregate loads, stores and phi nodes into operations on
432 // scalar types. This inserts extractvalue and insertvalue 433 // scalar types. This inserts extractvalue and insertvalue
433 // instructions which we will expand out later. 434 // instructions which we will expand out later.
434 for (Function::iterator BB = Func.begin(), E = Func.end(); BB != E; ++BB) { 435 for (Function::iterator BB = Func.begin(), E = Func.end(); BB != E; ++BB) {
435 for (BasicBlock::iterator Iter = BB->begin(), E = BB->end(); Iter != E;) { 436 for (BasicBlock::iterator Iter = BB->begin(), E = BB->end(); Iter != E;) {
436 Instruction *Inst = Iter++; 437 Instruction *Inst = Iter++;
437 if (StoreInst *Store = dyn_cast<StoreInst>(Inst)) { 438 if (StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
438 if (Store->getValueOperand()->getType()->isStructTy()) { 439 if (Store->getValueOperand()->getType()->isStructTy()) {
439 NeedsAnotherPass |= SplitUpStore(Store); 440 NeedsAnotherPass |= SplitUpStore(Store, DL);
440 Changed = true; 441 Changed = true;
441 } 442 }
442 } else if (LoadInst *Load = dyn_cast<LoadInst>(Inst)) { 443 } else if (LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
443 if (Load->getType()->isStructTy()) { 444 if (Load->getType()->isStructTy()) {
444 NeedsAnotherPass |= SplitUpLoad(Load); 445 NeedsAnotherPass |= SplitUpLoad(Load, DL);
445 Changed = true; 446 Changed = true;
446 } 447 }
447 } else if (PHINode *Phi = dyn_cast<PHINode>(Inst)) { 448 } else if (PHINode *Phi = dyn_cast<PHINode>(Inst)) {
448 if (Phi->getType()->isStructTy()) { 449 if (Phi->getType()->isStructTy()) {
449 NeedsAnotherPass |= SplitUpPHINode(Phi); 450 NeedsAnotherPass |= SplitUpPHINode(Phi);
450 Changed = true; 451 Changed = true;
451 } 452 }
452 } else if (SelectInst *Select = dyn_cast<SelectInst>(Inst)) { 453 } else if (SelectInst *Select = dyn_cast<SelectInst>(Inst)) {
453 if (Select->getType()->isStructTy()) { 454 if (Select->getType()->isStructTy()) {
454 NeedsAnotherPass |= SplitUpSelect(Select); 455 NeedsAnotherPass |= SplitUpSelect(Select);
455 Changed = true; 456 Changed = true;
456 } 457 }
457 } 458 }
458 } 459 }
459 } 460 }
460 } while (NeedsAnotherPass); 461 } while (NeedsAnotherPass);
461 462
462 Changed |= ExpandExtractValues(Func); 463 Changed |= ExpandExtractValues(Func);
463 464
464 return Changed; 465 return Changed;
465 } 466 }
466 467
467 FunctionPass *llvm::createExpandStructRegsPass() { 468 FunctionPass *llvm::createExpandStructRegsPass() {
468 return new ExpandStructRegs(); 469 return new ExpandStructRegs();
469 } 470 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698