OLD | NEW |
| (Empty) |
1 //==- ExpandInsertExtractElement.cpp - Expand vector insert and extract -=// | |
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 expands insertelement and extractelement instructions with | |
11 // variable indices, which SIMD.js doesn't natively support yet. | |
12 // | |
13 //===------------------------------------------------------------------===// | |
14 | |
15 #include "llvm/ADT/SmallVector.h" | |
16 #include "llvm/IR/Function.h" | |
17 #include "llvm/IR/IRBuilder.h" | |
18 #include "llvm/IR/InstIterator.h" | |
19 #include "llvm/IR/Instructions.h" | |
20 #include "llvm/IR/Module.h" | |
21 #include "llvm/Pass.h" | |
22 #include "llvm/Transforms/NaCl.h" | |
23 #include "llvm/Transforms/Utils/Local.h" | |
24 #include <map> | |
25 #include <vector> | |
26 | |
27 #include "llvm/Support/raw_ostream.h" | |
28 | |
29 #ifdef NDEBUG | |
30 #undef assert | |
31 #define assert(x) { if (!(x)) report_fatal_error(#x); } | |
32 #endif | |
33 | |
34 using namespace llvm; | |
35 | |
36 namespace { | |
37 | |
38 class ExpandInsertExtractElement : public FunctionPass { | |
39 bool Changed; | |
40 | |
41 public: | |
42 static char ID; | |
43 ExpandInsertExtractElement() : FunctionPass(ID) { | |
44 initializeExpandInsertExtractElementPass(*PassRegistry::getPassRegistry())
; | |
45 } | |
46 | |
47 virtual bool runOnFunction(Function &F); | |
48 }; | |
49 } | |
50 | |
51 char ExpandInsertExtractElement::ID = 0; | |
52 INITIALIZE_PASS(ExpandInsertExtractElement, "expand-insert-extract-elements", | |
53 "Expand and lower insert and extract element operations", | |
54 false, false) | |
55 | |
56 // Utilities | |
57 | |
58 bool ExpandInsertExtractElement::runOnFunction(Function &F) { | |
59 Changed = false; | |
60 | |
61 Instruction *Entry = F.getEntryBlock().begin(); | |
62 Type *Int32 = Type::getInt32Ty(F.getContext()); | |
63 Constant *Zero = ConstantInt::get(Int32, 0); | |
64 for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ) { | |
65 Instruction *Inst = &*I++; | |
66 | |
67 if (InsertElementInst *III = dyn_cast<InsertElementInst>(Inst)) { | |
68 if (isa<ConstantInt>(III->getOperand(2))) | |
69 continue; | |
70 | |
71 Type *AllocaTy = III->getType(); | |
72 Instruction *A = new AllocaInst(AllocaTy, 0, "", Entry); | |
73 CopyDebug(new StoreInst(III->getOperand(0), A, III), III); | |
74 | |
75 Value *Idxs[] = { Zero, III->getOperand(2) }; | |
76 Instruction *B = CopyDebug( | |
77 GetElementPtrInst::Create(AllocaTy, A, Idxs, "", III), III); | |
78 CopyDebug(new StoreInst(III->getOperand(1), B, III), III); | |
79 | |
80 Instruction *L = CopyDebug(new LoadInst(A, "", III), III); | |
81 III->replaceAllUsesWith(L); | |
82 III->eraseFromParent(); | |
83 } else if (ExtractElementInst *EII = dyn_cast<ExtractElementInst>(Inst)) { | |
84 if (isa<ConstantInt>(EII->getOperand(1))) | |
85 continue; | |
86 | |
87 Type *AllocaTy = EII->getOperand(0)->getType(); | |
88 Instruction *A = new AllocaInst(AllocaTy, 0, "", Entry); | |
89 CopyDebug(new StoreInst(EII->getOperand(0), A, EII), EII); | |
90 | |
91 Value *Idxs[] = { Zero, EII->getOperand(1) }; | |
92 Instruction *B = CopyDebug( | |
93 GetElementPtrInst::Create(AllocaTy, A, Idxs, "", EII), EII); | |
94 Instruction *L = CopyDebug(new LoadInst(B, "", EII), EII); | |
95 EII->replaceAllUsesWith(L); | |
96 EII->eraseFromParent(); | |
97 } | |
98 } | |
99 | |
100 return Changed; | |
101 } | |
102 | |
103 FunctionPass *llvm::createExpandInsertExtractElementPass() { | |
104 return new ExpandInsertExtractElement(); | |
105 } | |
OLD | NEW |