| 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 |