LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

LowerConstantExprs.cpp

Go to the documentation of this file.
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 }