[llvm-commits] CVS: llvm/lib/Transforms/Scalar/LowerConstantExprs.cpp
Chris Lattner
lattner at cs.uiuc.edu
Fri Jun 25 02:49:03 PDT 2004
Changes in directory llvm/lib/Transforms/Scalar:
LowerConstantExprs.cpp added (r1.1)
---
Log message:
New constant expression lowering pass to simplify your instruction selection needs.
Contributed by Vladimir Prus!
---
Diffs of the changes: (+171 -0)
Index: llvm/lib/Transforms/Scalar/LowerConstantExprs.cpp
diff -c /dev/null llvm/lib/Transforms/Scalar/LowerConstantExprs.cpp:1.1
*** /dev/null Fri Jun 25 02:48:19 2004
--- llvm/lib/Transforms/Scalar/LowerConstantExprs.cpp Fri Jun 25 02:48:09 2004
***************
*** 0 ****
--- 1,171 ----
+ //===-- lib/Transforms/Scalar/LowerConstantExprs.cpp ------------*- C++ -*-===//
+ //
+ // The LLVM Compiler Infrastructure
+ //
+ // This file was written by Vladimir Prus and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file defines the LowerConstantExpression pass, which converts all
+ // constant expressions into instructions. This is primarily usefull for
+ // code generators which don't yet want or don't have a need to handle
+ // constant expressions themself.
+ //
+ //===----------------------------------------------------------------------===//
+
+ #include "llvm/Pass.h"
+ #include "llvm/Function.h"
+ #include "llvm/Constants.h"
+ #include "llvm/iMemory.h"
+ #include "llvm/iPHINode.h"
+ #include "llvm/iOther.h"
+ #include "llvm/Support/InstIterator.h"
+ #include <vector>
+
+ using namespace llvm;
+ using namespace std;
+
+ namespace {
+
+ class ConstantExpressionsLower : public FunctionPass {
+ private: // FunctionPass overrides
+
+ bool runOnFunction(Function& f);
+
+ private: // internal methods
+
+ /// For all operands of 'insn' which are constant expressions, generates
+ /// an appropriate instruction and replaces the use of constant
+ /// expression with the use of the generated instruction.
+ bool runOnInstruction(Instruction& insn);
+
+ /// Given an constant expression 'c' which occures in 'instruction',
+ /// at position 'pos',
+ /// generates instruction to compute 'c' and replaces the use of 'c'
+ /// with the use of that instruction. This handles only top-level
+ /// expression in 'c', any subexpressions are not handled.
+ Instruction* convert(const ConstantExpr& c, Instruction* where);
+ };
+
+ RegisterOpt<ConstantExpressionsLower> X(
+ "lowerconstantexprs", "Lower constant expressions");
+ }
+
+ bool ConstantExpressionsLower::runOnFunction(Function& f)
+ {
+ bool modified = false;
+ for (inst_iterator i = inst_begin(f), e = inst_end(f); i != e; ++i)
+ {
+ modified |= runOnInstruction(*i);
+ }
+ return modified;
+ }
+
+ bool ConstantExpressionsLower::runOnInstruction(Instruction& instruction)
+ {
+ bool modified = false;
+ for (unsigned pos = 0; pos < instruction.getNumOperands(); ++pos)
+ {
+ if (ConstantExpr* ce
+ = dyn_cast<ConstantExpr>(instruction.getOperand(pos))) {
+
+ // Decide where to insert the new instruction
+ Instruction* where = &instruction;
+
+ // For PHI nodes we can't insert new instruction before phi,
+ // since phi should always come at the beginning of the
+ // basic block.
+ // So, we need to insert it in the predecessor, right before
+ // the terminating instruction.
+ if (PHINode* p = dyn_cast<PHINode>(&instruction)) {
+ BasicBlock* predecessor = 0;
+ for(unsigned i = 0; i < p->getNumIncomingValues(); ++i)
+ if (p->getIncomingValue(i) == ce) {
+ predecessor = p->getIncomingBlock(i);
+ break;
+ }
+ assert(predecessor && "could not find predecessor");
+ where = predecessor->getTerminator();
+ }
+ Instruction* n = convert(*ce, where);
+
+ // Note: we can't call replaceAllUsesWith, since
+ // that might replace uses in another functions,
+ // where the instruction(s) we've generated are not
+ // available.
+
+ // Moreover, we can't replace all the users in the same
+ // function, because we can't be sure the definition
+ // made in this block will be available in other
+ // places where the constant is used.
+ instruction.setOperand(pos, n);
+
+ // The new instruction might have constant expressions in
+ // it. Extract them too.
+ runOnInstruction(*n);
+ modified = true;
+ }
+ }
+ return modified;
+ }
+
+ Instruction*
+ ConstantExpressionsLower::convert(const ConstantExpr& c, Instruction* where)
+ {
+ Instruction* result = 0;
+
+ if (c.getOpcode() >= Instruction::BinaryOpsBegin &&
+ c.getOpcode() < Instruction::BinaryOpsEnd)
+ {
+ result = BinaryOperator::create(
+ static_cast<Instruction::BinaryOps>(c.getOpcode()),
+ c.getOperand(0), c.getOperand(1), "", where);
+ }
+ else
+ {
+ switch(c.getOpcode()) {
+ case Instruction::GetElementPtr:
+ {
+ vector<Value*> idx;
+ for (unsigned i = 1; i < c.getNumOperands(); ++i)
+ idx.push_back(c.getOperand(i));
+ result = new GetElementPtrInst(c.getOperand(0),
+ idx, "", where);
+ break;
+ }
+
+ case Instruction::Cast:
+ result = new CastInst(c.getOperand(0), c.getType(), "",
+ where);
+ break;
+
+
+ case Instruction::Shl:
+ case Instruction::Shr:
+ result = new ShiftInst(
+ static_cast<Instruction::OtherOps>(c.getOpcode()),
+ c.getOperand(0), c.getOperand(1), "", where);
+ break;
+
+ case Instruction::Select:
+ result = new SelectInst(c.getOperand(0), c.getOperand(1),
+ c.getOperand(2), "", where);
+ break;
+
+ default:
+ std::cerr << "Offending expr: " << c << "\n";
+ assert(0 && "Constant expression not yet handled!\n");
+ }
+ }
+ return result;
+ }
+
+
+
+ namespace llvm {
+ FunctionPass* createLowerConstantExpressionsPass()
+ {
+ return new ConstantExpressionsLower;
+ }
+ }
More information about the llvm-commits
mailing list