LLVM API Documentation
00001 //===-- lib/Transforms/Scalar/LowerConstantExprs.cpp ------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was written by Vladimir Prus and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the LowerConstantExpression pass, which converts all 00011 // constant expressions into instructions. This is primarily usefull for 00012 // code generators which don't yet want or don't have a need to handle 00013 // constant expressions themself. 00014 // 00015 //===----------------------------------------------------------------------===// 00016 00017 #include "llvm/Pass.h" 00018 #include "llvm/Function.h" 00019 #include "llvm/Constants.h" 00020 #include "llvm/Instructions.h" 00021 #include "llvm/Support/InstIterator.h" 00022 #include <vector> 00023 #include <iostream> 00024 00025 using namespace llvm; 00026 using namespace std; 00027 00028 namespace { 00029 00030 class ConstantExpressionsLower : public FunctionPass { 00031 private: // FunctionPass overrides 00032 00033 bool runOnFunction(Function& f); 00034 00035 private: // internal methods 00036 00037 /// For all operands of 'insn' which are constant expressions, generates 00038 /// an appropriate instruction and replaces the use of constant 00039 /// expression with the use of the generated instruction. 00040 bool runOnInstruction(Instruction& insn); 00041 00042 /// Given an constant expression 'c' which occures in 'instruction', 00043 /// at position 'pos', 00044 /// generates instruction to compute 'c' and replaces the use of 'c' 00045 /// with the use of that instruction. This handles only top-level 00046 /// expression in 'c', any subexpressions are not handled. 00047 Instruction* convert(const ConstantExpr& c, Instruction* where); 00048 }; 00049 00050 RegisterOpt<ConstantExpressionsLower> X( 00051 "lowerconstantexprs", "Lower constant expressions"); 00052 } 00053 00054 bool ConstantExpressionsLower::runOnFunction(Function& f) 00055 { 00056 bool modified = false; 00057 for (inst_iterator i = inst_begin(f), e = inst_end(f); i != e; ++i) 00058 { 00059 modified |= runOnInstruction(*i); 00060 } 00061 return modified; 00062 } 00063 00064 bool ConstantExpressionsLower::runOnInstruction(Instruction& instruction) 00065 { 00066 bool modified = false; 00067 for (unsigned pos = 0; pos < instruction.getNumOperands(); ++pos) 00068 { 00069 if (ConstantExpr* ce 00070 = dyn_cast<ConstantExpr>(instruction.getOperand(pos))) { 00071 00072 // Decide where to insert the new instruction 00073 Instruction* where = &instruction; 00074 00075 // For PHI nodes we can't insert new instruction before phi, 00076 // since phi should always come at the beginning of the 00077 // basic block. 00078 // So, we need to insert it in the predecessor, right before 00079 // the terminating instruction. 00080 if (PHINode* p = dyn_cast<PHINode>(&instruction)) { 00081 BasicBlock* predecessor = 0; 00082 for(unsigned i = 0; i < p->getNumIncomingValues(); ++i) 00083 if (p->getIncomingValue(i) == ce) { 00084 predecessor = p->getIncomingBlock(i); 00085 break; 00086 } 00087 assert(predecessor && "could not find predecessor"); 00088 where = predecessor->getTerminator(); 00089 } 00090 Instruction* n = convert(*ce, where); 00091 00092 // Note: we can't call replaceAllUsesWith, since 00093 // that might replace uses in another functions, 00094 // where the instruction(s) we've generated are not 00095 // available. 00096 00097 // Moreover, we can't replace all the users in the same 00098 // function, because we can't be sure the definition 00099 // made in this block will be available in other 00100 // places where the constant is used. 00101 instruction.setOperand(pos, n); 00102 00103 // The new instruction might have constant expressions in 00104 // it. Extract them too. 00105 runOnInstruction(*n); 00106 modified = true; 00107 } 00108 } 00109 return modified; 00110 } 00111 00112 Instruction* 00113 ConstantExpressionsLower::convert(const ConstantExpr& c, Instruction* where) 00114 { 00115 Instruction* result = 0; 00116 00117 if (c.getOpcode() >= Instruction::BinaryOpsBegin && 00118 c.getOpcode() < Instruction::BinaryOpsEnd) 00119 { 00120 result = BinaryOperator::create( 00121 static_cast<Instruction::BinaryOps>(c.getOpcode()), 00122 c.getOperand(0), c.getOperand(1), "", where); 00123 } 00124 else 00125 { 00126 switch(c.getOpcode()) { 00127 case Instruction::GetElementPtr: 00128 { 00129 vector<Value*> idx; 00130 for (unsigned i = 1; i < c.getNumOperands(); ++i) 00131 idx.push_back(c.getOperand(i)); 00132 result = new GetElementPtrInst(c.getOperand(0), 00133 idx, "", where); 00134 break; 00135 } 00136 00137 case Instruction::Cast: 00138 result = new CastInst(c.getOperand(0), c.getType(), "", 00139 where); 00140 break; 00141 00142 00143 case Instruction::Shl: 00144 case Instruction::Shr: 00145 result = new ShiftInst( 00146 static_cast<Instruction::OtherOps>(c.getOpcode()), 00147 c.getOperand(0), c.getOperand(1), "", where); 00148 break; 00149 00150 case Instruction::Select: 00151 result = new SelectInst(c.getOperand(0), c.getOperand(1), 00152 c.getOperand(2), "", where); 00153 break; 00154 00155 default: 00156 std::cerr << "Offending expr: " << c << "\n"; 00157 assert(0 && "Constant expression not yet handled!\n"); 00158 } 00159 } 00160 return result; 00161 } 00162 00163 00164 00165 namespace llvm { 00166 FunctionPass* createLowerConstantExpressionsPass() 00167 { 00168 return new ConstantExpressionsLower; 00169 } 00170 }