//===----------------------------------------------------------------------===//
#include "llvm/Analysis/Expressions.h"
-#include "llvm/Transforms/Scalar/ConstantHandling.h"
-#include "llvm/Method.h"
-#include "llvm/BasicBlock.h"
-#include <iostream>
-
-using namespace analysis;
+#include "llvm/ConstantHandling.h"
+#include "llvm/Function.h"
ExprType::ExprType(Value *Val) {
if (Val)
const ConstantInt *offset) {
Scale = var ? scale : 0; Var = var; Offset = offset;
ExprTy = Scale ? ScaledLinear : (Var ? Linear : Constant);
- if (Scale && Scale->equalsInt(0)) { // Simplify 0*Var + const
+ if (Scale && Scale->isNullValue()) { // Simplify 0*Var + const
Scale = 0; Var = 0;
ExprTy = Constant;
}
};
+// getUnsignedConstant - Return a constant value of the specified type. If the
+// constant value is not valid for the specified type, return null. This cannot
+// happen for values in the range of 0 to 127.
+//
static ConstantInt *getUnsignedConstant(uint64_t V, const Type *Ty) {
- if (Ty->isPointerType()) Ty = Type::ULongTy;
- return Ty->isSigned() ? (ConstantInt*)ConstantSInt::get(Ty, V)
- : (ConstantInt*)ConstantUInt::get(Ty, V);
+ if (isa<PointerType>(Ty)) Ty = Type::ULongTy;
+ if (Ty->isSigned()) {
+ // If this value is not a valid unsigned value for this type, return null!
+ if (V > 127 && ((int64_t)V < 0 ||
+ !ConstantSInt::isValueValidForType(Ty, (int64_t)V)))
+ return 0;
+ return ConstantSInt::get(Ty, V);
+ } else {
+ // If this value is not a valid unsigned value for this type, return null!
+ if (V > 255 && !ConstantUInt::isValueValidForType(Ty, V))
+ return 0;
+ return ConstantUInt::get(Ty, V);
+ }
}
// Add - Helper function to make later code simpler. Basically it just adds
// Note that this analysis cannot get into infinite loops because it treats PHI
// nodes as being an unknown linear expression.
//
-ExprType analysis::ClassifyExpression(Value *Expr) {
+ExprType ClassifyExpression(Value *Expr) {
assert(Expr != 0 && "Can't classify a null expression!");
if (Expr->getType() == Type::FloatTy || Expr->getType() == Type::DoubleTy)
return Expr; // FIXME: Can't handle FP expressions
switch (Expr->getValueType()) {
case Value::InstructionVal: break; // Instruction... hmmm... investigate.
case Value::TypeVal: case Value::BasicBlockVal:
- case Value::MethodVal: case Value::ModuleVal: default:
+ case Value::FunctionVal: default:
//assert(0 && "Unexpected expression type to classify!");
std::cerr << "Bizarre thing to expr classify: " << Expr << "\n";
return Expr;
- case Value::GlobalVariableVal: // Global Variable & Method argument:
- case Value::MethodArgumentVal: // nothing known, return variable itself
+ case Value::GlobalVariableVal: // Global Variable & Function argument:
+ case Value::ArgumentVal: // nothing known, return variable itself
return Expr;
case Value::ConstantVal: // Constant value, just return constant
- Constant *CPV = cast<Constant>(Expr);
- if (CPV->getType()->isIntegral()) { // It's an integral constant!
- ConstantInt *CPI = cast<ConstantInt>(Expr);
- return ExprType(CPI->equalsInt(0) ? 0 : CPI);
- }
+ if (ConstantInt *CPI = dyn_cast<ConstantInt>(cast<Constant>(Expr)))
+ // It's an integral constant!
+ return ExprType(CPI->isNullValue() ? 0 : CPI);
return Expr;
}
"Shift amount must always be a unsigned byte!");
uint64_t ShiftAmount = ((ConstantUInt*)Right.Offset)->getValue();
ConstantInt *Multiplier = getUnsignedConstant(1ULL << ShiftAmount, Ty);
-
+
+ // We don't know how to classify it if they are shifting by more than what
+ // is reasonable. In most cases, the result will be zero, but there is one
+ // class of cases where it is not, so we cannot optimize without checking
+ // for it. The case is when you are shifting a signed value by 1 less than
+ // the number of bits in the value. For example:
+ // %X = shl sbyte %Y, ubyte 7
+ // will try to form an sbyte multiplier of 128, which will give a null
+ // multiplier, even though the result is not 0. Until we can check for this
+ // case, be conservative. TODO.
+ //
+ if (Multiplier == 0)
+ return Expr;
+
return ExprType(DefOne(Left.Scale, Ty) * Multiplier, Left.Var,
DefZero(Left.Offset, Ty) * Multiplier);
} // end case Instruction::Shl
case Instruction::Cast: {
ExprType Src(ClassifyExpression(I->getOperand(0)));
const Type *DestTy = I->getType();
- if (DestTy->isPointerType())
+ if (isa<PointerType>(DestTy))
DestTy = Type::ULongTy; // Pointer types are represented as ulong
/*