OLD | NEW |
1 //===- ExpandI64.cpp - Expand i64 and wider integer types -------------===// | 1 //===- ExpandI64.cpp - Expand i64 and wider integer types -------------===// |
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 and lowers all operations on integers i64 and wider | 10 // This pass expands and lowers all operations on integers i64 and wider |
(...skipping 20 matching lines...) Expand all Loading... |
31 #include "llvm/Analysis/ConstantFolding.h" | 31 #include "llvm/Analysis/ConstantFolding.h" |
32 #include "llvm/Analysis/InstructionSimplify.h" | 32 #include "llvm/Analysis/InstructionSimplify.h" |
33 #include "llvm/IR/CFG.h" | 33 #include "llvm/IR/CFG.h" |
34 #include "llvm/IR/DataLayout.h" | 34 #include "llvm/IR/DataLayout.h" |
35 #include "llvm/IR/Function.h" | 35 #include "llvm/IR/Function.h" |
36 #include "llvm/IR/IRBuilder.h" | 36 #include "llvm/IR/IRBuilder.h" |
37 #include "llvm/IR/Instructions.h" | 37 #include "llvm/IR/Instructions.h" |
38 #include "llvm/IR/IntrinsicInst.h" | 38 #include "llvm/IR/IntrinsicInst.h" |
39 #include "llvm/IR/Module.h" | 39 #include "llvm/IR/Module.h" |
40 #include "llvm/Pass.h" | 40 #include "llvm/Pass.h" |
41 #include "llvm/Target/TargetLibraryInfo.h" | 41 #include "llvm/Analysis/TargetLibraryInfo.h" |
42 #include "llvm/Transforms/NaCl.h" | 42 #include "llvm/Transforms/NaCl.h" |
43 #include "llvm/Transforms/Utils/Local.h" | 43 #include "llvm/Transforms/Utils/Local.h" |
44 #include <map> | 44 #include <map> |
45 #include <vector> | 45 #include <vector> |
46 | 46 |
47 #include "llvm/Support/raw_ostream.h" | 47 #include "llvm/Support/raw_ostream.h" |
48 | 48 |
49 #ifdef NDEBUG | 49 #ifdef NDEBUG |
50 #undef assert | 50 #undef assert |
51 #define assert(x) { if (!(x)) report_fatal_error(#x); } | 51 #define assert(x) { if (!(x)) report_fatal_error(#x); } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 | 109 |
110 public: | 110 public: |
111 static char ID; | 111 static char ID; |
112 ExpandI64() : ModulePass(ID) { | 112 ExpandI64() : ModulePass(ID) { |
113 initializeExpandI64Pass(*PassRegistry::getPassRegistry()); | 113 initializeExpandI64Pass(*PassRegistry::getPassRegistry()); |
114 | 114 |
115 Add = Sub = Mul = SDiv = UDiv = SRem = URem = LShr = AShr = Shl = GetHigh
= SetHigh = NULL; | 115 Add = Sub = Mul = SDiv = UDiv = SRem = URem = LShr = AShr = Shl = GetHigh
= SetHigh = NULL; |
116 } | 116 } |
117 | 117 |
118 virtual bool runOnModule(Module &M); | 118 virtual bool runOnModule(Module &M); |
119 virtual void getAnalysisUsage(AnalysisUsage &AU) const; | |
120 }; | 119 }; |
121 } | 120 } |
122 | 121 |
123 char ExpandI64::ID = 0; | 122 char ExpandI64::ID = 0; |
124 INITIALIZE_PASS(ExpandI64, "expand-illegal-ints", | 123 INITIALIZE_PASS(ExpandI64, "expand-illegal-ints", |
125 "Expand and lower illegal >i32 operations into 32-bit chunks", | 124 "Expand and lower illegal >i32 operations into 32-bit chunks", |
126 false, false) | 125 false, false) |
127 | 126 |
128 // Utilities | 127 // Utilities |
129 | 128 |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 SmallVector<Value*, 2> NewOps; | 326 SmallVector<Value*, 2> NewOps; |
328 for (unsigned i = 1, e = I->getNumOperands(); i != e; ++i) { | 327 for (unsigned i = 1, e = I->getNumOperands(); i != e; ++i) { |
329 Value *Op = I->getOperand(i); | 328 Value *Op = I->getOperand(i); |
330 if (isIllegal(Op->getType())) { | 329 if (isIllegal(Op->getType())) { |
331 // Truncate the operand down to one chunk. | 330 // Truncate the operand down to one chunk. |
332 NewOps.push_back(getChunks(Op)[0]); | 331 NewOps.push_back(getChunks(Op)[0]); |
333 } else { | 332 } else { |
334 NewOps.push_back(Op); | 333 NewOps.push_back(Op); |
335 } | 334 } |
336 } | 335 } |
337 Value *NewGEP = CopyDebug(GetElementPtrInst::Create(GEP->getPointerOperand
(), NewOps, "", GEP), GEP); | 336 Value *NewGEP = CopyDebug(GetElementPtrInst::Create(GEP->getPointerOperand
()->getType(), GEP->getPointerOperand(), NewOps, "", GEP), GEP); |
338 Chunks.push_back(NewGEP); | 337 Chunks.push_back(NewGEP); |
339 I->replaceAllUsesWith(NewGEP); | 338 I->replaceAllUsesWith(NewGEP); |
340 break; | 339 break; |
341 } | 340 } |
342 case Instruction::SExt: { | 341 case Instruction::SExt: { |
343 ChunksVec InputChunks; | 342 ChunksVec InputChunks; |
344 Value *Op = I->getOperand(0); | 343 Value *Op = I->getOperand(0); |
345 if (isIllegal(Op->getType())) { | 344 if (isIllegal(Op->getType())) { |
346 InputChunks = getChunks(Op); | 345 InputChunks = getChunks(Op); |
347 } else { | 346 } else { |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 // shifted the complement-fractional amount to the other side | 594 // shifted the complement-fractional amount to the other side |
596 if (Comp != Zero && H != Zero) { | 595 if (Comp != Zero && H != Zero) { |
597 if (Fraction == 0) { | 596 if (Fraction == 0) { |
598 H = TopFiller; | 597 H = TopFiller; |
599 } else { | 598 } else { |
600 H = CopyDebug(BinaryOperator::Create(Reverse, H, Comp, "", I), I); | 599 H = CopyDebug(BinaryOperator::Create(Reverse, H, Comp, "", I), I); |
601 } | 600 } |
602 } | 601 } |
603 | 602 |
604 // Or the parts together. Since we may have zero, try to fold it away. | 603 // Or the parts together. Since we may have zero, try to fold it away. |
605 if (Value *V = SimplifyBinOp(Instruction::Or, L, H, DL)) { | 604 if (Value *V = SimplifyBinOp(Instruction::Or, L, H, *DL)) { |
606 Chunks.push_back(V); | 605 Chunks.push_back(V); |
607 } else { | 606 } else { |
608 Chunks.push_back(CopyDebug(BinaryOperator::Create(Instruction::Or, L
, H, "", I), I)); | 607 Chunks.push_back(CopyDebug(BinaryOperator::Create(Instruction::Or, L
, H, "", I), I)); |
609 } | 608 } |
610 } | 609 } |
611 } | 610 } |
612 break; | 611 break; |
613 } | 612 } |
614 case Instruction::ICmp: { | 613 case Instruction::ICmp: { |
615 ICmpInst *CE = cast<ICmpInst>(I); | 614 ICmpInst *CE = cast<ICmpInst>(I); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 case Instruction::Or: | 717 case Instruction::Or: |
719 case Instruction::Xor: { | 718 case Instruction::Xor: { |
720 BinaryOperator *BO = cast<BinaryOperator>(I); | 719 BinaryOperator *BO = cast<BinaryOperator>(I); |
721 ChunksVec LeftChunks = getChunks(BO->getOperand(0)); | 720 ChunksVec LeftChunks = getChunks(BO->getOperand(0)); |
722 ChunksVec RightChunks = getChunks(BO->getOperand(1)); | 721 ChunksVec RightChunks = getChunks(BO->getOperand(1)); |
723 int Num = getNumChunks(BO->getType()); | 722 int Num = getNumChunks(BO->getType()); |
724 for (int i = 0; i < Num; i++) { | 723 for (int i = 0; i < Num; i++) { |
725 // If there's a constant operand, it's likely enough that one of the | 724 // If there's a constant operand, it's likely enough that one of the |
726 // chunks will be a trivial operation, so it's worth calling | 725 // chunks will be a trivial operation, so it's worth calling |
727 // SimplifyBinOp here. | 726 // SimplifyBinOp here. |
728 if (Value *V = SimplifyBinOp(BO->getOpcode(), LeftChunks[i], RightChunks
[i], DL)) { | 727 if (Value *V = SimplifyBinOp(BO->getOpcode(), LeftChunks[i], RightChunks
[i], *DL)) { |
729 Chunks.push_back(V); | 728 Chunks.push_back(V); |
730 } else { | 729 } else { |
731 Chunks.push_back(CopyDebug(BinaryOperator::Create(BO->getOpcode(), Lef
tChunks[i], RightChunks[i], "", BO), BO)); | 730 Chunks.push_back(CopyDebug(BinaryOperator::Create(BO->getOpcode(), Lef
tChunks[i], RightChunks[i], "", BO), BO)); |
732 } | 731 } |
733 } | 732 } |
734 break; | 733 break; |
735 } | 734 } |
736 case Instruction::Call: { | 735 case Instruction::Call: { |
737 CallInst *CI = cast<CallInst>(I); | 736 CallInst *CI = cast<CallInst>(I); |
738 Function *F = CI->getCalledFunction(); | 737 Function *F = CI->getCalledFunction(); |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
948 if (isa<UndefValue>(V)) | 947 if (isa<UndefValue>(V)) |
949 return ChunksVec(Num, UndefValue::get(i32)); | 948 return ChunksVec(Num, UndefValue::get(i32)); |
950 | 949 |
951 if (Constant *C = dyn_cast<Constant>(V)) { | 950 if (Constant *C = dyn_cast<Constant>(V)) { |
952 ChunksVec Chunks; | 951 ChunksVec Chunks; |
953 for (unsigned i = 0; i < Num; i++) { | 952 for (unsigned i = 0; i < Num; i++) { |
954 Constant *Count = ConstantInt::get(C->getType(), i * 32); | 953 Constant *Count = ConstantInt::get(C->getType(), i * 32); |
955 Constant *NewC = ConstantExpr::getTrunc(ConstantExpr::getLShr(C, Count), i
32); | 954 Constant *NewC = ConstantExpr::getTrunc(ConstantExpr::getLShr(C, Count), i
32); |
956 TargetLibraryInfo *TLI = 0; // TODO | 955 TargetLibraryInfo *TLI = 0; // TODO |
957 if (ConstantExpr *NewCE = dyn_cast<ConstantExpr>(NewC)) { | 956 if (ConstantExpr *NewCE = dyn_cast<ConstantExpr>(NewC)) { |
958 if (Constant *FoldedC = ConstantFoldConstantExpression(NewCE, DL, TLI))
{ | 957 if (Constant *FoldedC = ConstantFoldConstantExpression(NewCE, *DL, TLI))
{ |
959 NewC = FoldedC; | 958 NewC = FoldedC; |
960 } | 959 } |
961 } | 960 } |
962 | 961 |
963 Chunks.push_back(NewC); | 962 Chunks.push_back(NewC); |
964 } | 963 } |
965 return Chunks; | 964 return Chunks; |
966 } | 965 } |
967 | 966 |
968 if (Splits.find(V) == Splits.end()) { | 967 if (Splits.find(V) == Splits.end()) { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1062 "SItoD", TheModule); | 1061 "SItoD", TheModule); |
1063 UItoD = Function::Create(ItoDFunc, GlobalValue::ExternalLinkage, | 1062 UItoD = Function::Create(ItoDFunc, GlobalValue::ExternalLinkage, |
1064 "UItoD", TheModule); | 1063 "UItoD", TheModule); |
1065 | 1064 |
1066 BItoD = Function::Create(ItoDFunc, GlobalValue::ExternalLinkage, | 1065 BItoD = Function::Create(ItoDFunc, GlobalValue::ExternalLinkage, |
1067 "BItoD", TheModule); | 1066 "BItoD", TheModule); |
1068 } | 1067 } |
1069 | 1068 |
1070 bool ExpandI64::runOnModule(Module &M) { | 1069 bool ExpandI64::runOnModule(Module &M) { |
1071 TheModule = &M; | 1070 TheModule = &M; |
1072 DL = &getAnalysis<DataLayoutPass>().getDataLayout(); | 1071 DL = &M.getDataLayout(); |
1073 Splits.clear(); | 1072 Splits.clear(); |
1074 Changed = false; | 1073 Changed = false; |
1075 | 1074 |
1076 // pre pass - legalize functions | 1075 // pre pass - legalize functions |
1077 for (Module::iterator Iter = M.begin(), E = M.end(); Iter != E; ) { | 1076 for (Module::iterator Iter = M.begin(), E = M.end(); Iter != E; ) { |
1078 Function *Func = Iter++; | 1077 Function *Func = Iter++; |
1079 ensureLegalFunc(Func); | 1078 ensureLegalFunc(Func); |
1080 } | 1079 } |
1081 | 1080 |
1082 // first pass - split | 1081 // first pass - split |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1150 // post pass - clean up illegal functions that were legalized. We do this | 1149 // post pass - clean up illegal functions that were legalized. We do this |
1151 // after the full walk of the functions so that all uses are replaced first. | 1150 // after the full walk of the functions so that all uses are replaced first. |
1152 for (Module::iterator Iter = M.begin(), E = M.end(); Iter != E; ) { | 1151 for (Module::iterator Iter = M.begin(), E = M.end(); Iter != E; ) { |
1153 Function *Func = Iter++; | 1152 Function *Func = Iter++; |
1154 removeIllegalFunc(Func); | 1153 removeIllegalFunc(Func); |
1155 } | 1154 } |
1156 | 1155 |
1157 return Changed; | 1156 return Changed; |
1158 } | 1157 } |
1159 | 1158 |
1160 void ExpandI64::getAnalysisUsage(AnalysisUsage &AU) const { | |
1161 AU.addRequired<DataLayoutPass>(); | |
1162 ModulePass::getAnalysisUsage(AU); | |
1163 } | |
1164 | |
1165 ModulePass *llvm::createExpandI64Pass() { | 1159 ModulePass *llvm::createExpandI64Pass() { |
1166 return new ExpandI64(); | 1160 return new ExpandI64(); |
1167 } | 1161 } |
OLD | NEW |