-//===- LevelRaise.cpp - Code to change LLVM to higher level -----------------=//
+//===- LevelRaise.cpp - Code to change LLVM to higher level ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
//
// This file implements the 'raising' part of the LevelChange API. This is
// useful because, in general, it makes the LLVM code terser and easier to
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/RaisePointerReferences.h"
+#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h"
#include "TransformInternals.h"
#include "llvm/iOther.h"
#include "llvm/iMemory.h"
#include "llvm/Pass.h"
-#include "llvm/ConstantHandling.h"
-#include "llvm/Analysis/Expressions.h"
-#include "llvm/Analysis/Verifier.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-#include "Support/STLExtras.h"
-#include "Support/Statistic.h"
#include "Support/CommandLine.h"
+#include "Support/Debug.h"
+#include "Support/Statistic.h"
+#include "Support/STLExtras.h"
#include <algorithm>
-using std::cerr;
+using namespace llvm;
// StartInst - This enables the -raise-start-inst=foo option to cause the level
// raising pass to start at instruction "foo", which is immensely useful for
static Statistic<>
NumVarargCallChanges("raise", "Number of vararg call peepholes");
-
#define PRINT_PEEPHOLE(ID, NUM, I) \
DEBUG(std::cerr << "Inst P/H " << ID << "[" << NUM << "] " << I)
RegisterOpt<RPR> X("raise", "Raise Pointer References");
}
-Pass *createRaisePointerReferencesPass() {
+
+Pass *llvm::createRaisePointerReferencesPass() {
return new RPR();
}
-
// isReinterpretingCast - Return true if the cast instruction specified will
// cause the operand to be "reinterpreted". A value is reinterpreted if the
// cast instruction would cause the underlying bits to change.
if (ExpressionConvertibleToType(Src, DestTy, ConvertedTypes, TD)) {
PRINT_PEEPHOLE3("CAST-SRC-EXPR-CONV:in ", Src, CI, BB->getParent());
- DEBUG(cerr << "\nCONVERTING SRC EXPR TYPE:\n");
+ DEBUG(std::cerr << "\nCONVERTING SRC EXPR TYPE:\n");
{ // ValueMap must be destroyed before function verified!
ValueMapCache ValueMap;
Value *E = ConvertExpressionToType(Src, DestTy, ValueMap, TD);
CI->replaceAllUsesWith(CPV);
PRINT_PEEPHOLE1("CAST-SRC-EXPR-CONV:out", E);
- DEBUG(cerr << "DONE CONVERTING SRC EXPR TYPE: \n" << BB->getParent());
+ DEBUG(std::cerr << "DONE CONVERTING SRC EXPR TYPE: \n"
+ << BB->getParent());
}
- DEBUG(assert(verifyFunction(*BB->getParent()) == false &&
- "Function broken!"));
BI = BB->begin(); // Rescan basic block. BI might be invalidated.
++NumExprTreesConv;
return true;
if (ValueConvertibleToType(CI, Src->getType(), ConvertedTypes, TD)) {
PRINT_PEEPHOLE3("CAST-DEST-EXPR-CONV:in ", Src, CI, BB->getParent());
- DEBUG(cerr << "\nCONVERTING EXPR TYPE:\n");
+ DEBUG(std::cerr << "\nCONVERTING EXPR TYPE:\n");
{ // ValueMap must be destroyed before function verified!
ValueMapCache ValueMap;
ConvertValueToNewType(CI, Src, ValueMap, TD); // This will delete CI!
}
PRINT_PEEPHOLE1("CAST-DEST-EXPR-CONV:out", Src);
- DEBUG(cerr << "DONE CONVERTING EXPR TYPE: \n\n" << BB->getParent());
+ DEBUG(std::cerr << "DONE CONVERTING EXPR TYPE: \n\n" << BB->getParent());
- DEBUG(assert(verifyFunction(*BB->getParent()) == false &&
- "Function broken!"));
BI = BB->begin(); // Rescan basic block. BI might be invalidated.
++NumExprTreesConv;
return true;
// Build the index vector, full of all zeros
std::vector<Value*> Indices;
- Indices.push_back(ConstantSInt::get(Type::LongTy, 0));
+
+ Indices.push_back(ConstantSInt::get(Type::LongTy, 0)); // FIXME, PR82
while (CurCTy && !isa<PointerType>(CurCTy)) {
+ const Type *IdxType;
if (const StructType *CurSTy = dyn_cast<StructType>(CurCTy)) {
// Check for a zero element struct type... if we have one, bail.
- if (CurSTy->getElementTypes().size() == 0) break;
+ if (CurSTy->getNumElements() == 0) break;
// Grab the first element of the struct type, which must lie at
// offset zero in the struct.
//
- ElTy = CurSTy->getElementTypes()[0];
+ ElTy = CurSTy->getElementType(0);
+ IdxType = Type::UByteTy; // FIXME when PR82 is fixed.
} else {
ElTy = cast<ArrayType>(CurCTy)->getElementType();
+ IdxType = Type::LongTy; // FIXME when PR82 is fixed.
}
// Insert a zero to index through this type...
- Indices.push_back(Constant::getNullValue(CurCTy->getIndexType()));
+ Indices.push_back(Constant::getNullValue(IdxType));
// Did we find what we're looking for?
if (ElTy->isLosslesslyConvertibleTo(DestPointedTy)) break;
NewCast = new CastInst(CI->getCalledValue(), NewPFunTy,
CI->getCalledValue()->getName()+"_c",CI);
+ // Strip off unneeded CPR's.
+ if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(NewCast))
+ NewCast = CPR->getValue();
+
// Create a new call instruction...
CallInst *NewCall = new CallInst(NewCast,
std::vector<Value*>(CI->op_begin()+1, CI->op_end()));
bool Changed = false;
for (Function::iterator BB = F.begin(), BBE = F.end(); BB != BBE; ++BB)
for (BasicBlock::iterator BI = BB->begin(); BI != BB->end();) {
- DEBUG(cerr << "Processing: " << *BI);
- if (dceInstruction(BI) || doConstantPropogation(BI)) {
+ DEBUG(std::cerr << "Processing: " << *BI);
+ if (dceInstruction(BI) || doConstantPropagation(BI)) {
Changed = true;
++NumDCEorCP;
- DEBUG(cerr << "***\t\t^^-- Dead code eliminated!\n");
+ DEBUG(std::cerr << "***\t\t^^-- Dead code eliminated!\n");
} else if (PeepholeOptimize(BB, BI)) {
Changed = true;
} else {
// runOnFunction - Raise a function representation to a higher level.
bool RPR::runOnFunction(Function &F) {
- DEBUG(cerr << "\n\n\nStarting to work on Function '" << F.getName() << "'\n");
+ DEBUG(std::cerr << "\n\n\nStarting to work on Function '" << F.getName()
+ << "'\n");
// Insert casts for all incoming pointer pointer values that are treated as
// arrays...
}
do {
- DEBUG(cerr << "Looping: \n" << F);
+ DEBUG(std::cerr << "Looping: \n" << F);
// Iterate over the function, refining it, until it converges on a stable
// state
return Changed;
}
+