mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-19 06:31:18 +00:00
Tidy up a bit. No functional change.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178915 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2da70d1792
commit
03fceff6f6
@ -9,7 +9,7 @@ add_llvm_library(LLVMInstCombine
|
|||||||
InstCombineMulDivRem.cpp
|
InstCombineMulDivRem.cpp
|
||||||
InstCombinePHI.cpp
|
InstCombinePHI.cpp
|
||||||
InstCombineSelect.cpp
|
InstCombineSelect.cpp
|
||||||
InstCombineShifts.cpp
|
InstCombineShifts.cpp
|
||||||
InstCombineSimplifyDemanded.cpp
|
InstCombineSimplifyDemanded.cpp
|
||||||
InstCombineVectorOps.cpp
|
InstCombineVectorOps.cpp
|
||||||
)
|
)
|
||||||
|
@ -24,9 +24,9 @@ namespace {
|
|||||||
/// Class representing coefficient of floating-point addend.
|
/// Class representing coefficient of floating-point addend.
|
||||||
/// This class needs to be highly efficient, which is especially true for
|
/// This class needs to be highly efficient, which is especially true for
|
||||||
/// the constructor. As of I write this comment, the cost of the default
|
/// the constructor. As of I write this comment, the cost of the default
|
||||||
/// constructor is merely 4-byte-store-zero (Assuming compiler is able to
|
/// constructor is merely 4-byte-store-zero (Assuming compiler is able to
|
||||||
/// perform write-merging).
|
/// perform write-merging).
|
||||||
///
|
///
|
||||||
class FAddendCoef {
|
class FAddendCoef {
|
||||||
public:
|
public:
|
||||||
// The constructor has to initialize a APFloat, which is uncessary for
|
// The constructor has to initialize a APFloat, which is uncessary for
|
||||||
@ -37,31 +37,31 @@ namespace {
|
|||||||
//
|
//
|
||||||
FAddendCoef() : IsFp(false), BufHasFpVal(false), IntVal(0) {}
|
FAddendCoef() : IsFp(false), BufHasFpVal(false), IntVal(0) {}
|
||||||
~FAddendCoef();
|
~FAddendCoef();
|
||||||
|
|
||||||
void set(short C) {
|
void set(short C) {
|
||||||
assert(!insaneIntVal(C) && "Insane coefficient");
|
assert(!insaneIntVal(C) && "Insane coefficient");
|
||||||
IsFp = false; IntVal = C;
|
IsFp = false; IntVal = C;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(const APFloat& C);
|
void set(const APFloat& C);
|
||||||
|
|
||||||
void negate();
|
void negate();
|
||||||
|
|
||||||
bool isZero() const { return isInt() ? !IntVal : getFpVal().isZero(); }
|
bool isZero() const { return isInt() ? !IntVal : getFpVal().isZero(); }
|
||||||
Value *getValue(Type *) const;
|
Value *getValue(Type *) const;
|
||||||
|
|
||||||
// If possible, don't define operator+/operator- etc because these
|
// If possible, don't define operator+/operator- etc because these
|
||||||
// operators inevitably call FAddendCoef's constructor which is not cheap.
|
// operators inevitably call FAddendCoef's constructor which is not cheap.
|
||||||
void operator=(const FAddendCoef &A);
|
void operator=(const FAddendCoef &A);
|
||||||
void operator+=(const FAddendCoef &A);
|
void operator+=(const FAddendCoef &A);
|
||||||
void operator-=(const FAddendCoef &A);
|
void operator-=(const FAddendCoef &A);
|
||||||
void operator*=(const FAddendCoef &S);
|
void operator*=(const FAddendCoef &S);
|
||||||
|
|
||||||
bool isOne() const { return isInt() && IntVal == 1; }
|
bool isOne() const { return isInt() && IntVal == 1; }
|
||||||
bool isTwo() const { return isInt() && IntVal == 2; }
|
bool isTwo() const { return isInt() && IntVal == 2; }
|
||||||
bool isMinusOne() const { return isInt() && IntVal == -1; }
|
bool isMinusOne() const { return isInt() && IntVal == -1; }
|
||||||
bool isMinusTwo() const { return isInt() && IntVal == -2; }
|
bool isMinusTwo() const { return isInt() && IntVal == -2; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool insaneIntVal(int V) { return V > 4 || V < -4; }
|
bool insaneIntVal(int V) { return V > 4 || V < -4; }
|
||||||
APFloat *getFpValPtr(void)
|
APFloat *getFpValPtr(void)
|
||||||
@ -74,26 +74,28 @@ namespace {
|
|||||||
return *getFpValPtr();
|
return *getFpValPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
APFloat &getFpVal(void)
|
APFloat &getFpVal(void) {
|
||||||
{ assert(IsFp && BufHasFpVal && "Incorret state"); return *getFpValPtr(); }
|
assert(IsFp && BufHasFpVal && "Incorret state");
|
||||||
|
return *getFpValPtr();
|
||||||
|
}
|
||||||
|
|
||||||
bool isInt() const { return !IsFp; }
|
bool isInt() const { return !IsFp; }
|
||||||
|
|
||||||
// If the coefficient is represented by an integer, promote it to a
|
// If the coefficient is represented by an integer, promote it to a
|
||||||
// floating point.
|
// floating point.
|
||||||
void convertToFpType(const fltSemantics &Sem);
|
void convertToFpType(const fltSemantics &Sem);
|
||||||
|
|
||||||
// Construct an APFloat from a signed integer.
|
// Construct an APFloat from a signed integer.
|
||||||
// TODO: We should get rid of this function when APFloat can be constructed
|
// TODO: We should get rid of this function when APFloat can be constructed
|
||||||
// from an *SIGNED* integer.
|
// from an *SIGNED* integer.
|
||||||
APFloat createAPFloatFromInt(const fltSemantics &Sem, int Val);
|
APFloat createAPFloatFromInt(const fltSemantics &Sem, int Val);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool IsFp;
|
bool IsFp;
|
||||||
|
|
||||||
// True iff FpValBuf contains an instance of APFloat.
|
// True iff FpValBuf contains an instance of APFloat.
|
||||||
bool BufHasFpVal;
|
bool BufHasFpVal;
|
||||||
|
|
||||||
// The integer coefficient of an individual addend is either 1 or -1,
|
// The integer coefficient of an individual addend is either 1 or -1,
|
||||||
// and we try to simplify at most 4 addends from neighboring at most
|
// and we try to simplify at most 4 addends from neighboring at most
|
||||||
// two instructions. So the range of <IntVal> falls in [-4, 4]. APInt
|
// two instructions. So the range of <IntVal> falls in [-4, 4]. APInt
|
||||||
@ -102,7 +104,7 @@ namespace {
|
|||||||
|
|
||||||
AlignedCharArrayUnion<APFloat> FpValBuf;
|
AlignedCharArrayUnion<APFloat> FpValBuf;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// FAddend is used to represent floating-point addend. An addend is
|
/// FAddend is used to represent floating-point addend. An addend is
|
||||||
/// represented as <C, V>, where the V is a symbolic value, and C is a
|
/// represented as <C, V>, where the V is a symbolic value, and C is a
|
||||||
/// constant coefficient. A constant addend is represented as <C, 0>.
|
/// constant coefficient. A constant addend is represented as <C, 0>.
|
||||||
@ -110,10 +112,10 @@ namespace {
|
|||||||
class FAddend {
|
class FAddend {
|
||||||
public:
|
public:
|
||||||
FAddend() { Val = 0; }
|
FAddend() { Val = 0; }
|
||||||
|
|
||||||
Value *getSymVal (void) const { return Val; }
|
Value *getSymVal (void) const { return Val; }
|
||||||
const FAddendCoef &getCoef(void) const { return Coeff; }
|
const FAddendCoef &getCoef(void) const { return Coeff; }
|
||||||
|
|
||||||
bool isConstant() const { return Val == 0; }
|
bool isConstant() const { return Val == 0; }
|
||||||
bool isZero() const { return Coeff.isZero(); }
|
bool isZero() const { return Coeff.isZero(); }
|
||||||
|
|
||||||
@ -122,17 +124,17 @@ namespace {
|
|||||||
{ Coeff.set(Coefficient); Val = V; }
|
{ Coeff.set(Coefficient); Val = V; }
|
||||||
void set(const ConstantFP* Coefficient, Value *V)
|
void set(const ConstantFP* Coefficient, Value *V)
|
||||||
{ Coeff.set(Coefficient->getValueAPF()); Val = V; }
|
{ Coeff.set(Coefficient->getValueAPF()); Val = V; }
|
||||||
|
|
||||||
void negate() { Coeff.negate(); }
|
void negate() { Coeff.negate(); }
|
||||||
|
|
||||||
/// Drill down the U-D chain one step to find the definition of V, and
|
/// Drill down the U-D chain one step to find the definition of V, and
|
||||||
/// try to break the definition into one or two addends.
|
/// try to break the definition into one or two addends.
|
||||||
static unsigned drillValueDownOneStep(Value* V, FAddend &A0, FAddend &A1);
|
static unsigned drillValueDownOneStep(Value* V, FAddend &A0, FAddend &A1);
|
||||||
|
|
||||||
/// Similar to FAddend::drillDownOneStep() except that the value being
|
/// Similar to FAddend::drillDownOneStep() except that the value being
|
||||||
/// splitted is the addend itself.
|
/// splitted is the addend itself.
|
||||||
unsigned drillAddendDownOneStep(FAddend &Addend0, FAddend &Addend1) const;
|
unsigned drillAddendDownOneStep(FAddend &Addend0, FAddend &Addend1) const;
|
||||||
|
|
||||||
void operator+=(const FAddend &T) {
|
void operator+=(const FAddend &T) {
|
||||||
assert((Val == T.Val) && "Symbolic-values disagree");
|
assert((Val == T.Val) && "Symbolic-values disagree");
|
||||||
Coeff += T.Coeff;
|
Coeff += T.Coeff;
|
||||||
@ -140,12 +142,12 @@ namespace {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void Scale(const FAddendCoef& ScaleAmt) { Coeff *= ScaleAmt; }
|
void Scale(const FAddendCoef& ScaleAmt) { Coeff *= ScaleAmt; }
|
||||||
|
|
||||||
// This addend has the value of "Coeff * Val".
|
// This addend has the value of "Coeff * Val".
|
||||||
Value *Val;
|
Value *Val;
|
||||||
FAddendCoef Coeff;
|
FAddendCoef Coeff;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// FAddCombine is the class for optimizing an unsafe fadd/fsub along
|
/// FAddCombine is the class for optimizing an unsafe fadd/fsub along
|
||||||
/// with its neighboring at most two instructions.
|
/// with its neighboring at most two instructions.
|
||||||
///
|
///
|
||||||
@ -153,17 +155,17 @@ namespace {
|
|||||||
public:
|
public:
|
||||||
FAddCombine(InstCombiner::BuilderTy *B) : Builder(B), Instr(0) {}
|
FAddCombine(InstCombiner::BuilderTy *B) : Builder(B), Instr(0) {}
|
||||||
Value *simplify(Instruction *FAdd);
|
Value *simplify(Instruction *FAdd);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef SmallVector<const FAddend*, 4> AddendVect;
|
typedef SmallVector<const FAddend*, 4> AddendVect;
|
||||||
|
|
||||||
Value *simplifyFAdd(AddendVect& V, unsigned InstrQuota);
|
Value *simplifyFAdd(AddendVect& V, unsigned InstrQuota);
|
||||||
|
|
||||||
Value *performFactorization(Instruction *I);
|
Value *performFactorization(Instruction *I);
|
||||||
|
|
||||||
/// Convert given addend to a Value
|
/// Convert given addend to a Value
|
||||||
Value *createAddendVal(const FAddend &A, bool& NeedNeg);
|
Value *createAddendVal(const FAddend &A, bool& NeedNeg);
|
||||||
|
|
||||||
/// Return the number of instructions needed to emit the N-ary addition.
|
/// Return the number of instructions needed to emit the N-ary addition.
|
||||||
unsigned calcInstrNumber(const AddendVect& Vect);
|
unsigned calcInstrNumber(const AddendVect& Vect);
|
||||||
Value *createFSub(Value *Opnd0, Value *Opnd1);
|
Value *createFSub(Value *Opnd0, Value *Opnd1);
|
||||||
@ -173,10 +175,10 @@ namespace {
|
|||||||
Value *createFNeg(Value *V);
|
Value *createFNeg(Value *V);
|
||||||
Value *createNaryFAdd(const AddendVect& Opnds, unsigned InstrQuota);
|
Value *createNaryFAdd(const AddendVect& Opnds, unsigned InstrQuota);
|
||||||
void createInstPostProc(Instruction *NewInst);
|
void createInstPostProc(Instruction *NewInst);
|
||||||
|
|
||||||
InstCombiner::BuilderTy *Builder;
|
InstCombiner::BuilderTy *Builder;
|
||||||
Instruction *Instr;
|
Instruction *Instr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Debugging stuff are clustered here.
|
// Debugging stuff are clustered here.
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@ -188,7 +190,7 @@ namespace {
|
|||||||
void incCreateInstNum() {}
|
void incCreateInstNum() {}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
@ -211,7 +213,7 @@ void FAddendCoef::set(const APFloat& C) {
|
|||||||
} else
|
} else
|
||||||
*P = C;
|
*P = C;
|
||||||
|
|
||||||
IsFp = BufHasFpVal = true;
|
IsFp = BufHasFpVal = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FAddendCoef::convertToFpType(const fltSemantics &Sem) {
|
void FAddendCoef::convertToFpType(const fltSemantics &Sem) {
|
||||||
@ -225,7 +227,7 @@ void FAddendCoef::convertToFpType(const fltSemantics &Sem) {
|
|||||||
new(P) APFloat(Sem, 0 - IntVal);
|
new(P) APFloat(Sem, 0 - IntVal);
|
||||||
P->changeSign();
|
P->changeSign();
|
||||||
}
|
}
|
||||||
IsFp = BufHasFpVal = true;
|
IsFp = BufHasFpVal = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
APFloat FAddendCoef::createAPFloatFromInt(const fltSemantics &Sem, int Val) {
|
APFloat FAddendCoef::createAPFloatFromInt(const fltSemantics &Sem, int Val) {
|
||||||
@ -254,14 +256,14 @@ void FAddendCoef::operator+=(const FAddendCoef &That) {
|
|||||||
getFpVal().add(That.getFpVal(), RndMode);
|
getFpVal().add(That.getFpVal(), RndMode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isInt()) {
|
if (isInt()) {
|
||||||
const APFloat &T = That.getFpVal();
|
const APFloat &T = That.getFpVal();
|
||||||
convertToFpType(T.getSemantics());
|
convertToFpType(T.getSemantics());
|
||||||
getFpVal().add(T, RndMode);
|
getFpVal().add(T, RndMode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
APFloat &T = getFpVal();
|
APFloat &T = getFpVal();
|
||||||
T.add(createAPFloatFromInt(T.getSemantics(), That.IntVal), RndMode);
|
T.add(createAPFloatFromInt(T.getSemantics(), That.IntVal), RndMode);
|
||||||
}
|
}
|
||||||
@ -275,7 +277,7 @@ void FAddendCoef::operator-=(const FAddendCoef &That) {
|
|||||||
getFpVal().subtract(That.getFpVal(), RndMode);
|
getFpVal().subtract(That.getFpVal(), RndMode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isInt()) {
|
if (isInt()) {
|
||||||
const APFloat &T = That.getFpVal();
|
const APFloat &T = That.getFpVal();
|
||||||
convertToFpType(T.getSemantics());
|
convertToFpType(T.getSemantics());
|
||||||
@ -303,7 +305,7 @@ void FAddendCoef::operator*=(const FAddendCoef &That) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fltSemantics &Semantic =
|
const fltSemantics &Semantic =
|
||||||
isInt() ? That.getFpVal().getSemantics() : getFpVal().getSemantics();
|
isInt() ? That.getFpVal().getSemantics() : getFpVal().getSemantics();
|
||||||
|
|
||||||
if (isInt())
|
if (isInt())
|
||||||
@ -338,11 +340,11 @@ Value *FAddendCoef::getValue(Type *Ty) const {
|
|||||||
// A - B <1, A>, <1,B>
|
// A - B <1, A>, <1,B>
|
||||||
// 0 - B <-1, B>
|
// 0 - B <-1, B>
|
||||||
// C * A, <C, A>
|
// C * A, <C, A>
|
||||||
// A + C <1, A> <C, NULL>
|
// A + C <1, A> <C, NULL>
|
||||||
// 0 +/- 0 <0, NULL> (corner case)
|
// 0 +/- 0 <0, NULL> (corner case)
|
||||||
//
|
//
|
||||||
// Legend: A and B are not constant, C is constant
|
// Legend: A and B are not constant, C is constant
|
||||||
//
|
//
|
||||||
unsigned FAddend::drillValueDownOneStep
|
unsigned FAddend::drillValueDownOneStep
|
||||||
(Value *Val, FAddend &Addend0, FAddend &Addend1) {
|
(Value *Val, FAddend &Addend0, FAddend &Addend1) {
|
||||||
Instruction *I = 0;
|
Instruction *I = 0;
|
||||||
@ -413,7 +415,7 @@ unsigned FAddend::drillAddendDownOneStep
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unsigned BreakNum = FAddend::drillValueDownOneStep(Val, Addend0, Addend1);
|
unsigned BreakNum = FAddend::drillValueDownOneStep(Val, Addend0, Addend1);
|
||||||
if (!BreakNum || Coeff.isOne())
|
if (!BreakNum || Coeff.isOne())
|
||||||
return BreakNum;
|
return BreakNum;
|
||||||
|
|
||||||
Addend0.Scale(Coeff);
|
Addend0.Scale(Coeff);
|
||||||
@ -435,10 +437,10 @@ unsigned FAddend::drillAddendDownOneStep
|
|||||||
Value *FAddCombine::performFactorization(Instruction *I) {
|
Value *FAddCombine::performFactorization(Instruction *I) {
|
||||||
assert((I->getOpcode() == Instruction::FAdd ||
|
assert((I->getOpcode() == Instruction::FAdd ||
|
||||||
I->getOpcode() == Instruction::FSub) && "Expect add/sub");
|
I->getOpcode() == Instruction::FSub) && "Expect add/sub");
|
||||||
|
|
||||||
Instruction *I0 = dyn_cast<Instruction>(I->getOperand(0));
|
Instruction *I0 = dyn_cast<Instruction>(I->getOperand(0));
|
||||||
Instruction *I1 = dyn_cast<Instruction>(I->getOperand(1));
|
Instruction *I1 = dyn_cast<Instruction>(I->getOperand(1));
|
||||||
|
|
||||||
if (!I0 || !I1 || I0->getOpcode() != I1->getOpcode())
|
if (!I0 || !I1 || I0->getOpcode() != I1->getOpcode())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -453,14 +455,14 @@ Value *FAddCombine::performFactorization(Instruction *I) {
|
|||||||
Value *Opnd1_0 = I1->getOperand(0);
|
Value *Opnd1_0 = I1->getOperand(0);
|
||||||
Value *Opnd1_1 = I1->getOperand(1);
|
Value *Opnd1_1 = I1->getOperand(1);
|
||||||
|
|
||||||
// Input Instr I Factor AddSub0 AddSub1
|
// Input Instr I Factor AddSub0 AddSub1
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
// (x*y) +/- (x*z) x y z
|
// (x*y) +/- (x*z) x y z
|
||||||
// (y/x) +/- (z/x) x y z
|
// (y/x) +/- (z/x) x y z
|
||||||
//
|
//
|
||||||
Value *Factor = 0;
|
Value *Factor = 0;
|
||||||
Value *AddSub0 = 0, *AddSub1 = 0;
|
Value *AddSub0 = 0, *AddSub1 = 0;
|
||||||
|
|
||||||
if (isMpy) {
|
if (isMpy) {
|
||||||
if (Opnd0_0 == Opnd1_0 || Opnd0_0 == Opnd1_1)
|
if (Opnd0_0 == Opnd1_0 || Opnd0_0 == Opnd1_1)
|
||||||
Factor = Opnd0_0;
|
Factor = Opnd0_0;
|
||||||
@ -492,7 +494,7 @@ Value *FAddCombine::performFactorization(Instruction *I) {
|
|||||||
|
|
||||||
if (isMpy)
|
if (isMpy)
|
||||||
return createFMul(Factor, NewAddSub);
|
return createFMul(Factor, NewAddSub);
|
||||||
|
|
||||||
return createFDiv(NewAddSub, Factor);
|
return createFDiv(NewAddSub, Factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,7 +508,7 @@ Value *FAddCombine::simplify(Instruction *I) {
|
|||||||
assert((I->getOpcode() == Instruction::FAdd ||
|
assert((I->getOpcode() == Instruction::FAdd ||
|
||||||
I->getOpcode() == Instruction::FSub) && "Expect add/sub");
|
I->getOpcode() == Instruction::FSub) && "Expect add/sub");
|
||||||
|
|
||||||
// Save the instruction before calling other member-functions.
|
// Save the instruction before calling other member-functions.
|
||||||
Instr = I;
|
Instr = I;
|
||||||
|
|
||||||
FAddend Opnd0, Opnd1, Opnd0_0, Opnd0_1, Opnd1_0, Opnd1_1;
|
FAddend Opnd0, Opnd1, Opnd0_0, Opnd0_1, Opnd1_0, Opnd1_1;
|
||||||
@ -517,7 +519,7 @@ Value *FAddCombine::simplify(Instruction *I) {
|
|||||||
unsigned Opnd0_ExpNum = 0;
|
unsigned Opnd0_ExpNum = 0;
|
||||||
unsigned Opnd1_ExpNum = 0;
|
unsigned Opnd1_ExpNum = 0;
|
||||||
|
|
||||||
if (!Opnd0.isConstant())
|
if (!Opnd0.isConstant())
|
||||||
Opnd0_ExpNum = Opnd0.drillAddendDownOneStep(Opnd0_0, Opnd0_1);
|
Opnd0_ExpNum = Opnd0.drillAddendDownOneStep(Opnd0_0, Opnd0_1);
|
||||||
|
|
||||||
// Step 2: Expand the 2nd addend into Opnd1_0 and Opnd1_1.
|
// Step 2: Expand the 2nd addend into Opnd1_0 and Opnd1_1.
|
||||||
@ -539,7 +541,7 @@ Value *FAddCombine::simplify(Instruction *I) {
|
|||||||
|
|
||||||
Value *V0 = I->getOperand(0);
|
Value *V0 = I->getOperand(0);
|
||||||
Value *V1 = I->getOperand(1);
|
Value *V1 = I->getOperand(1);
|
||||||
InstQuota = ((!isa<Constant>(V0) && V0->hasOneUse()) &&
|
InstQuota = ((!isa<Constant>(V0) && V0->hasOneUse()) &&
|
||||||
(!isa<Constant>(V1) && V1->hasOneUse())) ? 2 : 1;
|
(!isa<Constant>(V1) && V1->hasOneUse())) ? 2 : 1;
|
||||||
|
|
||||||
if (Value *R = simplifyFAdd(AllOpnds, InstQuota))
|
if (Value *R = simplifyFAdd(AllOpnds, InstQuota))
|
||||||
@ -579,7 +581,7 @@ Value *FAddCombine::simplify(Instruction *I) {
|
|||||||
return R;
|
return R;
|
||||||
}
|
}
|
||||||
|
|
||||||
// step 6: Try factorization as the last resort,
|
// step 6: Try factorization as the last resort,
|
||||||
return performFactorization(I);
|
return performFactorization(I);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,7 +590,7 @@ Value *FAddCombine::simplifyFAdd(AddendVect& Addends, unsigned InstrQuota) {
|
|||||||
unsigned AddendNum = Addends.size();
|
unsigned AddendNum = Addends.size();
|
||||||
assert(AddendNum <= 4 && "Too many addends");
|
assert(AddendNum <= 4 && "Too many addends");
|
||||||
|
|
||||||
// For saving intermediate results;
|
// For saving intermediate results;
|
||||||
unsigned NextTmpIdx = 0;
|
unsigned NextTmpIdx = 0;
|
||||||
FAddend TmpResult[3];
|
FAddend TmpResult[3];
|
||||||
|
|
||||||
@ -604,7 +606,7 @@ Value *FAddCombine::simplifyFAdd(AddendVect& Addends, unsigned InstrQuota) {
|
|||||||
AddendVect SimpVect;
|
AddendVect SimpVect;
|
||||||
|
|
||||||
// The outer loop works on one symbolic-value at a time. Suppose the input
|
// The outer loop works on one symbolic-value at a time. Suppose the input
|
||||||
// addends are : <a1, x>, <b1, y>, <a2, x>, <c1, z>, <b2, y>, ...
|
// addends are : <a1, x>, <b1, y>, <a2, x>, <c1, z>, <b2, y>, ...
|
||||||
// The symbolic-values will be processed in this order: x, y, z.
|
// The symbolic-values will be processed in this order: x, y, z.
|
||||||
//
|
//
|
||||||
for (unsigned SymIdx = 0; SymIdx < AddendNum; SymIdx++) {
|
for (unsigned SymIdx = 0; SymIdx < AddendNum; SymIdx++) {
|
||||||
@ -631,7 +633,7 @@ Value *FAddCombine::simplifyFAdd(AddendVect& Addends, unsigned InstrQuota) {
|
|||||||
if (T && T->getSymVal() == Val) {
|
if (T && T->getSymVal() == Val) {
|
||||||
// Set null such that next iteration of the outer loop will not process
|
// Set null such that next iteration of the outer loop will not process
|
||||||
// this addend again.
|
// this addend again.
|
||||||
Addends[SameSymIdx] = 0;
|
Addends[SameSymIdx] = 0;
|
||||||
SimpVect.push_back(T);
|
SimpVect.push_back(T);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -644,7 +646,7 @@ Value *FAddCombine::simplifyFAdd(AddendVect& Addends, unsigned InstrQuota) {
|
|||||||
R += *SimpVect[Idx];
|
R += *SimpVect[Idx];
|
||||||
|
|
||||||
// Pop all addends being folded and push the resulting folded addend.
|
// Pop all addends being folded and push the resulting folded addend.
|
||||||
SimpVect.resize(StartIdx);
|
SimpVect.resize(StartIdx);
|
||||||
if (Val != 0) {
|
if (Val != 0) {
|
||||||
if (!R.isZero()) {
|
if (!R.isZero()) {
|
||||||
SimpVect.push_back(&R);
|
SimpVect.push_back(&R);
|
||||||
@ -657,7 +659,7 @@ Value *FAddCombine::simplifyFAdd(AddendVect& Addends, unsigned InstrQuota) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert((NextTmpIdx <= sizeof(TmpResult)/sizeof(TmpResult[0]) + 1) &&
|
assert((NextTmpIdx <= sizeof(TmpResult)/sizeof(TmpResult[0]) + 1) &&
|
||||||
"out-of-bound access");
|
"out-of-bound access");
|
||||||
|
|
||||||
if (ConstAdd)
|
if (ConstAdd)
|
||||||
@ -679,7 +681,7 @@ Value *FAddCombine::createNaryFAdd
|
|||||||
assert(!Opnds.empty() && "Expect at least one addend");
|
assert(!Opnds.empty() && "Expect at least one addend");
|
||||||
|
|
||||||
// Step 1: Check if the # of instructions needed exceeds the quota.
|
// Step 1: Check if the # of instructions needed exceeds the quota.
|
||||||
//
|
//
|
||||||
unsigned InstrNeeded = calcInstrNumber(Opnds);
|
unsigned InstrNeeded = calcInstrNumber(Opnds);
|
||||||
if (InstrNeeded > InstrQuota)
|
if (InstrNeeded > InstrQuota)
|
||||||
return 0;
|
return 0;
|
||||||
@ -700,7 +702,7 @@ Value *FAddCombine::createNaryFAdd
|
|||||||
// Iterate the addends, creating fadd/fsub using adjacent two addends.
|
// Iterate the addends, creating fadd/fsub using adjacent two addends.
|
||||||
for (AddendVect::const_iterator I = Opnds.begin(), E = Opnds.end();
|
for (AddendVect::const_iterator I = Opnds.begin(), E = Opnds.end();
|
||||||
I != E; I++) {
|
I != E; I++) {
|
||||||
bool NeedNeg;
|
bool NeedNeg;
|
||||||
Value *V = createAddendVal(**I, NeedNeg);
|
Value *V = createAddendVal(**I, NeedNeg);
|
||||||
if (!LastVal) {
|
if (!LastVal) {
|
||||||
LastVal = V;
|
LastVal = V;
|
||||||
@ -726,7 +728,7 @@ Value *FAddCombine::createNaryFAdd
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
assert(CreateInstrNum == InstrNeeded &&
|
assert(CreateInstrNum == InstrNeeded &&
|
||||||
"Inconsistent in instruction numbers");
|
"Inconsistent in instruction numbers");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -784,8 +786,8 @@ unsigned FAddCombine::calcInstrNumber(const AddendVect &Opnds) {
|
|||||||
unsigned OpndNum = Opnds.size();
|
unsigned OpndNum = Opnds.size();
|
||||||
unsigned InstrNeeded = OpndNum - 1;
|
unsigned InstrNeeded = OpndNum - 1;
|
||||||
|
|
||||||
// The number of addends in the form of "(-1)*x".
|
// The number of addends in the form of "(-1)*x".
|
||||||
unsigned NegOpndNum = 0;
|
unsigned NegOpndNum = 0;
|
||||||
|
|
||||||
// Adjust the number of instructions needed to emit the N-ary add.
|
// Adjust the number of instructions needed to emit the N-ary add.
|
||||||
for (AddendVect::const_iterator I = Opnds.begin(), E = Opnds.end();
|
for (AddendVect::const_iterator I = Opnds.begin(), E = Opnds.end();
|
||||||
|
@ -266,9 +266,8 @@ Instruction *InstCombiner::OptAndOp(Instruction *Op,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Emit a computation of: (V >= Lo && V < Hi) if Inside is true, otherwise
|
||||||
/// InsertRangeTest - Emit a computation of: (V >= Lo && V < Hi) if Inside is
|
/// (V < Lo || V >= Hi). In practice, we emit the more efficient
|
||||||
/// true, otherwise (V < Lo || V >= Hi). In practice, we emit the more efficient
|
|
||||||
/// (V-Lo) \<u Hi-Lo. This method expects that Lo <= Hi. isSigned indicates
|
/// (V-Lo) \<u Hi-Lo. This method expects that Lo <= Hi. isSigned indicates
|
||||||
/// whether to treat the V, Lo and HI as signed or not. IB is the location to
|
/// whether to treat the V, Lo and HI as signed or not. IB is the location to
|
||||||
/// insert new instructions.
|
/// insert new instructions.
|
||||||
|
@ -1372,7 +1372,8 @@ InstCombiner::transformCallThroughTrampoline(CallSite CS,
|
|||||||
NestF->getType() == PointerType::getUnqual(NewFTy) ?
|
NestF->getType() == PointerType::getUnqual(NewFTy) ?
|
||||||
NestF : ConstantExpr::getBitCast(NestF,
|
NestF : ConstantExpr::getBitCast(NestF,
|
||||||
PointerType::getUnqual(NewFTy));
|
PointerType::getUnqual(NewFTy));
|
||||||
const AttributeSet &NewPAL = AttributeSet::get(FTy->getContext(), NewAttrs);
|
const AttributeSet &NewPAL =
|
||||||
|
AttributeSet::get(FTy->getContext(), NewAttrs);
|
||||||
|
|
||||||
Instruction *NewCaller;
|
Instruction *NewCaller;
|
||||||
if (InvokeInst *II = dyn_cast<InvokeInst>(Caller)) {
|
if (InvokeInst *II = dyn_cast<InvokeInst>(Caller)) {
|
||||||
|
@ -232,7 +232,7 @@ FoldCmpLoadFromIndexedGlobal(GetElementPtrInst *GEP, GlobalVariable *GV,
|
|||||||
Constant *Init = GV->getInitializer();
|
Constant *Init = GV->getInitializer();
|
||||||
if (!isa<ConstantArray>(Init) && !isa<ConstantDataArray>(Init))
|
if (!isa<ConstantArray>(Init) && !isa<ConstantDataArray>(Init))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
uint64_t ArrayElementCount = Init->getType()->getArrayNumElements();
|
uint64_t ArrayElementCount = Init->getType()->getArrayNumElements();
|
||||||
if (ArrayElementCount > 1024) return 0; // Don't blow up on huge arrays.
|
if (ArrayElementCount > 1024) return 0; // Don't blow up on huge arrays.
|
||||||
|
|
||||||
|
@ -69,8 +69,8 @@ isOnlyCopiedFromConstantGlobal(Value *V, MemTransferInst *&TheCopy,
|
|||||||
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(U)) {
|
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(U)) {
|
||||||
// If the GEP has all zero indices, it doesn't offset the pointer. If it
|
// If the GEP has all zero indices, it doesn't offset the pointer. If it
|
||||||
// doesn't, it does.
|
// doesn't, it does.
|
||||||
if (!isOnlyCopiedFromConstantGlobal(GEP, TheCopy, ToDelete,
|
if (!isOnlyCopiedFromConstantGlobal(
|
||||||
IsOffset || !GEP->hasAllZeroIndices()))
|
GEP, TheCopy, ToDelete, IsOffset || !GEP->hasAllZeroIndices()))
|
||||||
return false;
|
return false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -166,7 +166,7 @@ Instruction *InstCombiner::visitAllocaInst(AllocaInst &AI) {
|
|||||||
// Convert: alloca Ty, C - where C is a constant != 1 into: alloca [C x Ty], 1
|
// Convert: alloca Ty, C - where C is a constant != 1 into: alloca [C x Ty], 1
|
||||||
if (AI.isArrayAllocation()) { // Check C != 1
|
if (AI.isArrayAllocation()) { // Check C != 1
|
||||||
if (const ConstantInt *C = dyn_cast<ConstantInt>(AI.getArraySize())) {
|
if (const ConstantInt *C = dyn_cast<ConstantInt>(AI.getArraySize())) {
|
||||||
Type *NewTy =
|
Type *NewTy =
|
||||||
ArrayType::get(AI.getAllocatedType(), C->getZExtValue());
|
ArrayType::get(AI.getAllocatedType(), C->getZExtValue());
|
||||||
AllocaInst *New = Builder->CreateAlloca(NewTy, 0, AI.getName());
|
AllocaInst *New = Builder->CreateAlloca(NewTy, 0, AI.getName());
|
||||||
New->setAlignment(AI.getAlignment());
|
New->setAlignment(AI.getAlignment());
|
||||||
@ -294,7 +294,7 @@ static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI,
|
|||||||
|
|
||||||
Type *SrcPTy = SrcTy->getElementType();
|
Type *SrcPTy = SrcTy->getElementType();
|
||||||
|
|
||||||
if (DestPTy->isIntegerTy() || DestPTy->isPointerTy() ||
|
if (DestPTy->isIntegerTy() || DestPTy->isPointerTy() ||
|
||||||
DestPTy->isVectorTy()) {
|
DestPTy->isVectorTy()) {
|
||||||
// If the source is an array, the code below will not succeed. Check to
|
// If the source is an array, the code below will not succeed. Check to
|
||||||
// see if a trivial 'gep P, 0, 0' will help matters. Only do this for
|
// see if a trivial 'gep P, 0, 0' will help matters. Only do this for
|
||||||
@ -311,7 +311,7 @@ static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (IC.getDataLayout() &&
|
if (IC.getDataLayout() &&
|
||||||
(SrcPTy->isIntegerTy() || SrcPTy->isPointerTy() ||
|
(SrcPTy->isIntegerTy() || SrcPTy->isPointerTy() ||
|
||||||
SrcPTy->isVectorTy()) &&
|
SrcPTy->isVectorTy()) &&
|
||||||
// Do not allow turning this into a load of an integer, which is then
|
// Do not allow turning this into a load of an integer, which is then
|
||||||
// casted to a pointer, this pessimizes pointer analysis a lot.
|
// casted to a pointer, this pessimizes pointer analysis a lot.
|
||||||
@ -322,7 +322,7 @@ static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI,
|
|||||||
// Okay, we are casting from one integer or pointer type to another of
|
// Okay, we are casting from one integer or pointer type to another of
|
||||||
// the same size. Instead of casting the pointer before the load, cast
|
// the same size. Instead of casting the pointer before the load, cast
|
||||||
// the result of the loaded value.
|
// the result of the loaded value.
|
||||||
LoadInst *NewLoad =
|
LoadInst *NewLoad =
|
||||||
IC.Builder->CreateLoad(CastOp, LI.isVolatile(), CI->getName());
|
IC.Builder->CreateLoad(CastOp, LI.isVolatile(), CI->getName());
|
||||||
NewLoad->setAlignment(LI.getAlignment());
|
NewLoad->setAlignment(LI.getAlignment());
|
||||||
NewLoad->setAtomic(LI.getOrdering(), LI.getSynchScope());
|
NewLoad->setAtomic(LI.getOrdering(), LI.getSynchScope());
|
||||||
@ -359,7 +359,7 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
|
|||||||
// None of the following transforms are legal for volatile/atomic loads.
|
// None of the following transforms are legal for volatile/atomic loads.
|
||||||
// FIXME: Some of it is okay for atomic loads; needs refactoring.
|
// FIXME: Some of it is okay for atomic loads; needs refactoring.
|
||||||
if (!LI.isSimple()) return 0;
|
if (!LI.isSimple()) return 0;
|
||||||
|
|
||||||
// Do really simple store-to-load forwarding and load CSE, to catch cases
|
// Do really simple store-to-load forwarding and load CSE, to catch cases
|
||||||
// where there are several consecutive memory accesses to the same location,
|
// where there are several consecutive memory accesses to the same location,
|
||||||
// separated by a few arithmetic operations.
|
// separated by a few arithmetic operations.
|
||||||
@ -380,7 +380,7 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
|
|||||||
Constant::getNullValue(Op->getType()), &LI);
|
Constant::getNullValue(Op->getType()), &LI);
|
||||||
return ReplaceInstUsesWith(LI, UndefValue::get(LI.getType()));
|
return ReplaceInstUsesWith(LI, UndefValue::get(LI.getType()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// load null/undef -> unreachable
|
// load null/undef -> unreachable
|
||||||
// TODO: Consider a target hook for valid address spaces for this xform.
|
// TODO: Consider a target hook for valid address spaces for this xform.
|
||||||
@ -399,7 +399,7 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
|
|||||||
if (CE->isCast())
|
if (CE->isCast())
|
||||||
if (Instruction *Res = InstCombineLoadCast(*this, LI, TD))
|
if (Instruction *Res = InstCombineLoadCast(*this, LI, TD))
|
||||||
return Res;
|
return Res;
|
||||||
|
|
||||||
if (Op->hasOneUse()) {
|
if (Op->hasOneUse()) {
|
||||||
// Change select and PHI nodes to select values instead of addresses: this
|
// Change select and PHI nodes to select values instead of addresses: this
|
||||||
// helps alias analysis out a lot, allows many others simplifications, and
|
// helps alias analysis out a lot, allows many others simplifications, and
|
||||||
@ -453,18 +453,18 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
|
|||||||
Type *DestPTy = cast<PointerType>(CI->getType())->getElementType();
|
Type *DestPTy = cast<PointerType>(CI->getType())->getElementType();
|
||||||
PointerType *SrcTy = dyn_cast<PointerType>(CastOp->getType());
|
PointerType *SrcTy = dyn_cast<PointerType>(CastOp->getType());
|
||||||
if (SrcTy == 0) return 0;
|
if (SrcTy == 0) return 0;
|
||||||
|
|
||||||
Type *SrcPTy = SrcTy->getElementType();
|
Type *SrcPTy = SrcTy->getElementType();
|
||||||
|
|
||||||
if (!DestPTy->isIntegerTy() && !DestPTy->isPointerTy())
|
if (!DestPTy->isIntegerTy() && !DestPTy->isPointerTy())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/// NewGEPIndices - If SrcPTy is an aggregate type, we can emit a "noop gep"
|
/// NewGEPIndices - If SrcPTy is an aggregate type, we can emit a "noop gep"
|
||||||
/// to its first element. This allows us to handle things like:
|
/// to its first element. This allows us to handle things like:
|
||||||
/// store i32 xxx, (bitcast {foo*, float}* %P to i32*)
|
/// store i32 xxx, (bitcast {foo*, float}* %P to i32*)
|
||||||
/// on 32-bit hosts.
|
/// on 32-bit hosts.
|
||||||
SmallVector<Value*, 4> NewGEPIndices;
|
SmallVector<Value*, 4> NewGEPIndices;
|
||||||
|
|
||||||
// If the source is an array, the code below will not succeed. Check to
|
// If the source is an array, the code below will not succeed. Check to
|
||||||
// see if a trivial 'gep P, 0, 0' will help matters. Only do this for
|
// see if a trivial 'gep P, 0, 0' will help matters. Only do this for
|
||||||
// constants.
|
// constants.
|
||||||
@ -472,7 +472,7 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
|
|||||||
// Index through pointer.
|
// Index through pointer.
|
||||||
Constant *Zero = Constant::getNullValue(Type::getInt32Ty(SI.getContext()));
|
Constant *Zero = Constant::getNullValue(Type::getInt32Ty(SI.getContext()));
|
||||||
NewGEPIndices.push_back(Zero);
|
NewGEPIndices.push_back(Zero);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (StructType *STy = dyn_cast<StructType>(SrcPTy)) {
|
if (StructType *STy = dyn_cast<StructType>(SrcPTy)) {
|
||||||
if (!STy->getNumElements()) /* Struct can be empty {} */
|
if (!STy->getNumElements()) /* Struct can be empty {} */
|
||||||
@ -486,24 +486,24 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SrcTy = PointerType::get(SrcPTy, SrcTy->getAddressSpace());
|
SrcTy = PointerType::get(SrcPTy, SrcTy->getAddressSpace());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SrcPTy->isIntegerTy() && !SrcPTy->isPointerTy())
|
if (!SrcPTy->isIntegerTy() && !SrcPTy->isPointerTy())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// If the pointers point into different address spaces or if they point to
|
// If the pointers point into different address spaces or if they point to
|
||||||
// values with different sizes, we can't do the transformation.
|
// values with different sizes, we can't do the transformation.
|
||||||
if (!IC.getDataLayout() ||
|
if (!IC.getDataLayout() ||
|
||||||
SrcTy->getAddressSpace() !=
|
SrcTy->getAddressSpace() !=
|
||||||
cast<PointerType>(CI->getType())->getAddressSpace() ||
|
cast<PointerType>(CI->getType())->getAddressSpace() ||
|
||||||
IC.getDataLayout()->getTypeSizeInBits(SrcPTy) !=
|
IC.getDataLayout()->getTypeSizeInBits(SrcPTy) !=
|
||||||
IC.getDataLayout()->getTypeSizeInBits(DestPTy))
|
IC.getDataLayout()->getTypeSizeInBits(DestPTy))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Okay, we are casting from one integer or pointer type to another of
|
// Okay, we are casting from one integer or pointer type to another of
|
||||||
// the same size. Instead of casting the pointer before
|
// the same size. Instead of casting the pointer before
|
||||||
// the store, cast the value to be stored.
|
// the store, cast the value to be stored.
|
||||||
Value *NewCast;
|
Value *NewCast;
|
||||||
Value *SIOp0 = SI.getOperand(0);
|
Value *SIOp0 = SI.getOperand(0);
|
||||||
@ -517,12 +517,12 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
|
|||||||
if (SIOp0->getType()->isPointerTy())
|
if (SIOp0->getType()->isPointerTy())
|
||||||
opcode = Instruction::PtrToInt;
|
opcode = Instruction::PtrToInt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SIOp0 is a pointer to aggregate and this is a store to the first field,
|
// SIOp0 is a pointer to aggregate and this is a store to the first field,
|
||||||
// emit a GEP to index into its first field.
|
// emit a GEP to index into its first field.
|
||||||
if (!NewGEPIndices.empty())
|
if (!NewGEPIndices.empty())
|
||||||
CastOp = IC.Builder->CreateInBoundsGEP(CastOp, NewGEPIndices);
|
CastOp = IC.Builder->CreateInBoundsGEP(CastOp, NewGEPIndices);
|
||||||
|
|
||||||
NewCast = IC.Builder->CreateCast(opcode, SIOp0, CastDstTy,
|
NewCast = IC.Builder->CreateCast(opcode, SIOp0, CastDstTy,
|
||||||
SIOp0->getName()+".c");
|
SIOp0->getName()+".c");
|
||||||
SI.setOperand(0, NewCast);
|
SI.setOperand(0, NewCast);
|
||||||
@ -541,7 +541,7 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
|
|||||||
static bool equivalentAddressValues(Value *A, Value *B) {
|
static bool equivalentAddressValues(Value *A, Value *B) {
|
||||||
// Test if the values are trivially equivalent.
|
// Test if the values are trivially equivalent.
|
||||||
if (A == B) return true;
|
if (A == B) return true;
|
||||||
|
|
||||||
// Test if the values come form identical arithmetic instructions.
|
// Test if the values come form identical arithmetic instructions.
|
||||||
// This uses isIdenticalToWhenDefined instead of isIdenticalTo because
|
// This uses isIdenticalToWhenDefined instead of isIdenticalTo because
|
||||||
// its only used to compare two uses within the same basic block, which
|
// its only used to compare two uses within the same basic block, which
|
||||||
@ -554,7 +554,7 @@ static bool equivalentAddressValues(Value *A, Value *B) {
|
|||||||
if (Instruction *BI = dyn_cast<Instruction>(B))
|
if (Instruction *BI = dyn_cast<Instruction>(B))
|
||||||
if (cast<Instruction>(A)->isIdenticalToWhenDefined(BI))
|
if (cast<Instruction>(A)->isIdenticalToWhenDefined(BI))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Otherwise they may not be equivalent.
|
// Otherwise they may not be equivalent.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -585,7 +585,7 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) {
|
|||||||
// If the RHS is an alloca with a single use, zapify the store, making the
|
// If the RHS is an alloca with a single use, zapify the store, making the
|
||||||
// alloca dead.
|
// alloca dead.
|
||||||
if (Ptr->hasOneUse()) {
|
if (Ptr->hasOneUse()) {
|
||||||
if (isa<AllocaInst>(Ptr))
|
if (isa<AllocaInst>(Ptr))
|
||||||
return EraseInstFromFunction(SI);
|
return EraseInstFromFunction(SI);
|
||||||
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Ptr)) {
|
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Ptr)) {
|
||||||
if (isa<AllocaInst>(GEP->getOperand(0))) {
|
if (isa<AllocaInst>(GEP->getOperand(0))) {
|
||||||
@ -608,8 +608,8 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) {
|
|||||||
(isa<BitCastInst>(BBI) && BBI->getType()->isPointerTy())) {
|
(isa<BitCastInst>(BBI) && BBI->getType()->isPointerTy())) {
|
||||||
ScanInsts++;
|
ScanInsts++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StoreInst *PrevSI = dyn_cast<StoreInst>(BBI)) {
|
if (StoreInst *PrevSI = dyn_cast<StoreInst>(BBI)) {
|
||||||
// Prev store isn't volatile, and stores to the same location?
|
// Prev store isn't volatile, and stores to the same location?
|
||||||
if (PrevSI->isSimple() && equivalentAddressValues(PrevSI->getOperand(1),
|
if (PrevSI->isSimple() && equivalentAddressValues(PrevSI->getOperand(1),
|
||||||
@ -621,7 +621,7 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is a load, we have to stop. However, if the loaded value is from
|
// If this is a load, we have to stop. However, if the loaded value is from
|
||||||
// the pointer we're loading and is producing the pointer we're storing,
|
// the pointer we're loading and is producing the pointer we're storing,
|
||||||
// then *this* store is dead (X = load P; store X -> P).
|
// then *this* store is dead (X = load P; store X -> P).
|
||||||
@ -629,12 +629,12 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) {
|
|||||||
if (LI == Val && equivalentAddressValues(LI->getOperand(0), Ptr) &&
|
if (LI == Val && equivalentAddressValues(LI->getOperand(0), Ptr) &&
|
||||||
LI->isSimple())
|
LI->isSimple())
|
||||||
return EraseInstFromFunction(SI);
|
return EraseInstFromFunction(SI);
|
||||||
|
|
||||||
// Otherwise, this is a load from some other location. Stores before it
|
// Otherwise, this is a load from some other location. Stores before it
|
||||||
// may not be dead.
|
// may not be dead.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't skip over loads or things that can modify memory.
|
// Don't skip over loads or things that can modify memory.
|
||||||
if (BBI->mayWriteToMemory() || BBI->mayReadFromMemory())
|
if (BBI->mayWriteToMemory() || BBI->mayReadFromMemory())
|
||||||
break;
|
break;
|
||||||
@ -664,11 +664,11 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) {
|
|||||||
if (Instruction *Res = InstCombineStoreToCast(*this, SI))
|
if (Instruction *Res = InstCombineStoreToCast(*this, SI))
|
||||||
return Res;
|
return Res;
|
||||||
|
|
||||||
|
|
||||||
// If this store is the last instruction in the basic block (possibly
|
// If this store is the last instruction in the basic block (possibly
|
||||||
// excepting debug info instructions), and if the block ends with an
|
// excepting debug info instructions), and if the block ends with an
|
||||||
// unconditional branch, try to move it to the successor block.
|
// unconditional branch, try to move it to the successor block.
|
||||||
BBI = &SI;
|
BBI = &SI;
|
||||||
do {
|
do {
|
||||||
++BBI;
|
++BBI;
|
||||||
} while (isa<DbgInfoIntrinsic>(BBI) ||
|
} while (isa<DbgInfoIntrinsic>(BBI) ||
|
||||||
@ -677,7 +677,7 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) {
|
|||||||
if (BI->isUnconditional())
|
if (BI->isUnconditional())
|
||||||
if (SimplifyStoreAtEndOfBlock(SI))
|
if (SimplifyStoreAtEndOfBlock(SI))
|
||||||
return 0; // xform done!
|
return 0; // xform done!
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -691,12 +691,12 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) {
|
|||||||
///
|
///
|
||||||
bool InstCombiner::SimplifyStoreAtEndOfBlock(StoreInst &SI) {
|
bool InstCombiner::SimplifyStoreAtEndOfBlock(StoreInst &SI) {
|
||||||
BasicBlock *StoreBB = SI.getParent();
|
BasicBlock *StoreBB = SI.getParent();
|
||||||
|
|
||||||
// Check to see if the successor block has exactly two incoming edges. If
|
// Check to see if the successor block has exactly two incoming edges. If
|
||||||
// so, see if the other predecessor contains a store to the same location.
|
// so, see if the other predecessor contains a store to the same location.
|
||||||
// if so, insert a PHI node (if needed) and move the stores down.
|
// if so, insert a PHI node (if needed) and move the stores down.
|
||||||
BasicBlock *DestBB = StoreBB->getTerminator()->getSuccessor(0);
|
BasicBlock *DestBB = StoreBB->getTerminator()->getSuccessor(0);
|
||||||
|
|
||||||
// Determine whether Dest has exactly two predecessors and, if so, compute
|
// Determine whether Dest has exactly two predecessors and, if so, compute
|
||||||
// the other predecessor.
|
// the other predecessor.
|
||||||
pred_iterator PI = pred_begin(DestBB);
|
pred_iterator PI = pred_begin(DestBB);
|
||||||
@ -708,7 +708,7 @@ bool InstCombiner::SimplifyStoreAtEndOfBlock(StoreInst &SI) {
|
|||||||
|
|
||||||
if (++PI == pred_end(DestBB))
|
if (++PI == pred_end(DestBB))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
P = *PI;
|
P = *PI;
|
||||||
if (P != StoreBB) {
|
if (P != StoreBB) {
|
||||||
if (OtherBB)
|
if (OtherBB)
|
||||||
@ -728,7 +728,7 @@ bool InstCombiner::SimplifyStoreAtEndOfBlock(StoreInst &SI) {
|
|||||||
BranchInst *OtherBr = dyn_cast<BranchInst>(BBI);
|
BranchInst *OtherBr = dyn_cast<BranchInst>(BBI);
|
||||||
if (!OtherBr || BBI == OtherBB->begin())
|
if (!OtherBr || BBI == OtherBB->begin())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// If the other block ends in an unconditional branch, check for the 'if then
|
// If the other block ends in an unconditional branch, check for the 'if then
|
||||||
// else' case. there is an instruction before the branch.
|
// else' case. there is an instruction before the branch.
|
||||||
StoreInst *OtherStore = 0;
|
StoreInst *OtherStore = 0;
|
||||||
@ -750,10 +750,10 @@ bool InstCombiner::SimplifyStoreAtEndOfBlock(StoreInst &SI) {
|
|||||||
} else {
|
} else {
|
||||||
// Otherwise, the other block ended with a conditional branch. If one of the
|
// Otherwise, the other block ended with a conditional branch. If one of the
|
||||||
// destinations is StoreBB, then we have the if/then case.
|
// destinations is StoreBB, then we have the if/then case.
|
||||||
if (OtherBr->getSuccessor(0) != StoreBB &&
|
if (OtherBr->getSuccessor(0) != StoreBB &&
|
||||||
OtherBr->getSuccessor(1) != StoreBB)
|
OtherBr->getSuccessor(1) != StoreBB)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Okay, we know that OtherBr now goes to Dest and StoreBB, so this is an
|
// Okay, we know that OtherBr now goes to Dest and StoreBB, so this is an
|
||||||
// if/then triangle. See if there is a store to the same ptr as SI that
|
// if/then triangle. See if there is a store to the same ptr as SI that
|
||||||
// lives in OtherBB.
|
// lives in OtherBB.
|
||||||
@ -771,7 +771,7 @@ bool InstCombiner::SimplifyStoreAtEndOfBlock(StoreInst &SI) {
|
|||||||
BBI == OtherBB->begin())
|
BBI == OtherBB->begin())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// In order to eliminate the store in OtherBr, we have to
|
// In order to eliminate the store in OtherBr, we have to
|
||||||
// make sure nothing reads or overwrites the stored value in
|
// make sure nothing reads or overwrites the stored value in
|
||||||
// StoreBB.
|
// StoreBB.
|
||||||
@ -781,7 +781,7 @@ bool InstCombiner::SimplifyStoreAtEndOfBlock(StoreInst &SI) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert a PHI node now if we need it.
|
// Insert a PHI node now if we need it.
|
||||||
Value *MergedVal = OtherStore->getOperand(0);
|
Value *MergedVal = OtherStore->getOperand(0);
|
||||||
if (MergedVal != SI.getOperand(0)) {
|
if (MergedVal != SI.getOperand(0)) {
|
||||||
@ -790,7 +790,7 @@ bool InstCombiner::SimplifyStoreAtEndOfBlock(StoreInst &SI) {
|
|||||||
PN->addIncoming(OtherStore->getOperand(0), OtherBB);
|
PN->addIncoming(OtherStore->getOperand(0), OtherBB);
|
||||||
MergedVal = InsertNewInstBefore(PN, DestBB->front());
|
MergedVal = InsertNewInstBefore(PN, DestBB->front());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance to a place where it is safe to insert the new store and
|
// Advance to a place where it is safe to insert the new store and
|
||||||
// insert it.
|
// insert it.
|
||||||
BBI = DestBB->getFirstInsertionPt();
|
BBI = DestBB->getFirstInsertionPt();
|
||||||
@ -800,7 +800,7 @@ bool InstCombiner::SimplifyStoreAtEndOfBlock(StoreInst &SI) {
|
|||||||
SI.getOrdering(),
|
SI.getOrdering(),
|
||||||
SI.getSynchScope());
|
SI.getSynchScope());
|
||||||
InsertNewInstBefore(NewSI, *BBI);
|
InsertNewInstBefore(NewSI, *BBI);
|
||||||
NewSI->setDebugLoc(OtherStore->getDebugLoc());
|
NewSI->setDebugLoc(OtherStore->getDebugLoc());
|
||||||
|
|
||||||
// If the two stores had the same TBAA tag, preserve it.
|
// If the two stores had the same TBAA tag, preserve it.
|
||||||
if (MDNode *TBAATag = SI.getMetadata(LLVMContext::MD_tbaa))
|
if (MDNode *TBAATag = SI.getMetadata(LLVMContext::MD_tbaa))
|
||||||
@ -808,7 +808,7 @@ bool InstCombiner::SimplifyStoreAtEndOfBlock(StoreInst &SI) {
|
|||||||
OtherStore->getMetadata(LLVMContext::MD_tbaa))))
|
OtherStore->getMetadata(LLVMContext::MD_tbaa))))
|
||||||
NewSI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
|
NewSI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
|
||||||
|
|
||||||
|
|
||||||
// Nuke the old stores.
|
// Nuke the old stores.
|
||||||
EraseInstFromFunction(SI);
|
EraseInstFromFunction(SI);
|
||||||
EraseInstFromFunction(*OtherStore);
|
EraseInstFromFunction(*OtherStore);
|
||||||
|
@ -28,7 +28,7 @@ static Value *simplifyValueKnownNonZero(Value *V, InstCombiner &IC) {
|
|||||||
// if this is safe. For example, the use could be in dynamically unreached
|
// if this is safe. For example, the use could be in dynamically unreached
|
||||||
// code.
|
// code.
|
||||||
if (!V->hasOneUse()) return 0;
|
if (!V->hasOneUse()) return 0;
|
||||||
|
|
||||||
bool MadeChange = false;
|
bool MadeChange = false;
|
||||||
|
|
||||||
// ((1 << A) >>u B) --> (1 << (A-B))
|
// ((1 << A) >>u B) --> (1 << (A-B))
|
||||||
@ -41,7 +41,7 @@ static Value *simplifyValueKnownNonZero(Value *V, InstCombiner &IC) {
|
|||||||
A = IC.Builder->CreateSub(A, B);
|
A = IC.Builder->CreateSub(A, B);
|
||||||
return IC.Builder->CreateShl(PowerOf2, A);
|
return IC.Builder->CreateShl(PowerOf2, A);
|
||||||
}
|
}
|
||||||
|
|
||||||
// (PowerOfTwo >>u B) --> isExact since shifting out the result would make it
|
// (PowerOfTwo >>u B) --> isExact since shifting out the result would make it
|
||||||
// inexact. Similarly for <<.
|
// inexact. Similarly for <<.
|
||||||
if (BinaryOperator *I = dyn_cast<BinaryOperator>(V))
|
if (BinaryOperator *I = dyn_cast<BinaryOperator>(V))
|
||||||
@ -52,12 +52,12 @@ static Value *simplifyValueKnownNonZero(Value *V, InstCombiner &IC) {
|
|||||||
I->setOperand(0, V2);
|
I->setOperand(0, V2);
|
||||||
MadeChange = true;
|
MadeChange = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (I->getOpcode() == Instruction::LShr && !I->isExact()) {
|
if (I->getOpcode() == Instruction::LShr && !I->isExact()) {
|
||||||
I->setIsExact();
|
I->setIsExact();
|
||||||
MadeChange = true;
|
MadeChange = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (I->getOpcode() == Instruction::Shl && !I->hasNoUnsignedWrap()) {
|
if (I->getOpcode() == Instruction::Shl && !I->hasNoUnsignedWrap()) {
|
||||||
I->setHasNoUnsignedWrap();
|
I->setHasNoUnsignedWrap();
|
||||||
MadeChange = true;
|
MadeChange = true;
|
||||||
@ -67,7 +67,7 @@ static Value *simplifyValueKnownNonZero(Value *V, InstCombiner &IC) {
|
|||||||
// TODO: Lots more we could do here:
|
// TODO: Lots more we could do here:
|
||||||
// If V is a phi node, we can call this on each of its operands.
|
// If V is a phi node, we can call this on each of its operands.
|
||||||
// "select cond, X, 0" can simplify to "X".
|
// "select cond, X, 0" can simplify to "X".
|
||||||
|
|
||||||
return MadeChange ? V : 0;
|
return MadeChange ? V : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,12 +84,12 @@ static bool MultiplyOverflows(ConstantInt *C1, ConstantInt *C2, bool sign) {
|
|||||||
LHSExt = LHSExt.zext(W * 2);
|
LHSExt = LHSExt.zext(W * 2);
|
||||||
RHSExt = RHSExt.zext(W * 2);
|
RHSExt = RHSExt.zext(W * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
APInt MulExt = LHSExt * RHSExt;
|
APInt MulExt = LHSExt * RHSExt;
|
||||||
|
|
||||||
if (!sign)
|
if (!sign)
|
||||||
return MulExt.ugt(APInt::getLowBitsSet(W * 2, W));
|
return MulExt.ugt(APInt::getLowBitsSet(W * 2, W));
|
||||||
|
|
||||||
APInt Min = APInt::getSignedMinValue(W).sext(W * 2);
|
APInt Min = APInt::getSignedMinValue(W).sext(W * 2);
|
||||||
APInt Max = APInt::getSignedMaxValue(W).sext(W * 2);
|
APInt Max = APInt::getSignedMaxValue(W).sext(W * 2);
|
||||||
return MulExt.slt(Min) || MulExt.sgt(Max);
|
return MulExt.slt(Min) || MulExt.sgt(Max);
|
||||||
@ -107,16 +107,16 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
|
|||||||
|
|
||||||
if (match(Op1, m_AllOnes())) // X * -1 == 0 - X
|
if (match(Op1, m_AllOnes())) // X * -1 == 0 - X
|
||||||
return BinaryOperator::CreateNeg(Op0, I.getName());
|
return BinaryOperator::CreateNeg(Op0, I.getName());
|
||||||
|
|
||||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
|
||||||
|
|
||||||
// ((X << C1)*C2) == (X * (C2 << C1))
|
// ((X << C1)*C2) == (X * (C2 << C1))
|
||||||
if (BinaryOperator *SI = dyn_cast<BinaryOperator>(Op0))
|
if (BinaryOperator *SI = dyn_cast<BinaryOperator>(Op0))
|
||||||
if (SI->getOpcode() == Instruction::Shl)
|
if (SI->getOpcode() == Instruction::Shl)
|
||||||
if (Constant *ShOp = dyn_cast<Constant>(SI->getOperand(1)))
|
if (Constant *ShOp = dyn_cast<Constant>(SI->getOperand(1)))
|
||||||
return BinaryOperator::CreateMul(SI->getOperand(0),
|
return BinaryOperator::CreateMul(SI->getOperand(0),
|
||||||
ConstantExpr::getShl(CI, ShOp));
|
ConstantExpr::getShl(CI, ShOp));
|
||||||
|
|
||||||
const APInt &Val = CI->getValue();
|
const APInt &Val = CI->getValue();
|
||||||
if (Val.isPowerOf2()) { // Replace X*(2^C) with X << C
|
if (Val.isPowerOf2()) { // Replace X*(2^C) with X << C
|
||||||
Constant *NewCst = ConstantInt::get(Op0->getType(), Val.logBase2());
|
Constant *NewCst = ConstantInt::get(Op0->getType(), Val.logBase2());
|
||||||
@ -125,7 +125,7 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
|
|||||||
if (I.hasNoUnsignedWrap()) Shl->setHasNoUnsignedWrap();
|
if (I.hasNoUnsignedWrap()) Shl->setHasNoUnsignedWrap();
|
||||||
return Shl;
|
return Shl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Canonicalize (X+C1)*CI -> X*CI+C1*CI.
|
// Canonicalize (X+C1)*CI -> X*CI+C1*CI.
|
||||||
{ Value *X; ConstantInt *C1;
|
{ Value *X; ConstantInt *C1;
|
||||||
if (Op0->hasOneUse() &&
|
if (Op0->hasOneUse() &&
|
||||||
@ -158,9 +158,9 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simplify mul instructions with a constant RHS.
|
// Simplify mul instructions with a constant RHS.
|
||||||
if (isa<Constant>(Op1)) {
|
if (isa<Constant>(Op1)) {
|
||||||
// Try to fold constant mul into select arguments.
|
// Try to fold constant mul into select arguments.
|
||||||
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
|
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
|
||||||
if (Instruction *R = FoldOpIntoSelect(I, SI))
|
if (Instruction *R = FoldOpIntoSelect(I, SI))
|
||||||
@ -181,7 +181,7 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
|
|||||||
Value *Op1C = Op1;
|
Value *Op1C = Op1;
|
||||||
BinaryOperator *BO = dyn_cast<BinaryOperator>(Op0);
|
BinaryOperator *BO = dyn_cast<BinaryOperator>(Op0);
|
||||||
if (!BO ||
|
if (!BO ||
|
||||||
(BO->getOpcode() != Instruction::UDiv &&
|
(BO->getOpcode() != Instruction::UDiv &&
|
||||||
BO->getOpcode() != Instruction::SDiv)) {
|
BO->getOpcode() != Instruction::SDiv)) {
|
||||||
Op1C = Op0;
|
Op1C = Op0;
|
||||||
BO = dyn_cast<BinaryOperator>(Op1);
|
BO = dyn_cast<BinaryOperator>(Op1);
|
||||||
@ -227,14 +227,14 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
|
|||||||
if (match(Op1, m_Shl(m_One(), m_Value(Y))))
|
if (match(Op1, m_Shl(m_One(), m_Value(Y))))
|
||||||
return BinaryOperator::CreateShl(Op0, Y);
|
return BinaryOperator::CreateShl(Op0, Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If one of the operands of the multiply is a cast from a boolean value, then
|
// If one of the operands of the multiply is a cast from a boolean value, then
|
||||||
// we know the bool is either zero or one, so this is a 'masking' multiply.
|
// we know the bool is either zero or one, so this is a 'masking' multiply.
|
||||||
// X * Y (where Y is 0 or 1) -> X & (0-Y)
|
// X * Y (where Y is 0 or 1) -> X & (0-Y)
|
||||||
if (!I.getType()->isVectorTy()) {
|
if (!I.getType()->isVectorTy()) {
|
||||||
// -2 is "-1 << 1" so it is all bits set except the low one.
|
// -2 is "-1 << 1" so it is all bits set except the low one.
|
||||||
APInt Negative2(I.getType()->getPrimitiveSizeInBits(), (uint64_t)-2, true);
|
APInt Negative2(I.getType()->getPrimitiveSizeInBits(), (uint64_t)-2, true);
|
||||||
|
|
||||||
Value *BoolCast = 0, *OtherOp = 0;
|
Value *BoolCast = 0, *OtherOp = 0;
|
||||||
if (MaskedValueIsZero(Op0, Negative2))
|
if (MaskedValueIsZero(Op0, Negative2))
|
||||||
BoolCast = Op0, OtherOp = Op1;
|
BoolCast = Op0, OtherOp = Op1;
|
||||||
@ -280,7 +280,7 @@ static void detectLog2OfHalf(Value *&Op, Value *&Y, IntrinsicInst *&Log2) {
|
|||||||
return;
|
return;
|
||||||
if (I->getOpcode() != Instruction::FMul || !I->hasUnsafeAlgebra())
|
if (I->getOpcode() != Instruction::FMul || !I->hasUnsafeAlgebra())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ConstantFP *CFP = dyn_cast<ConstantFP>(I->getOperand(0));
|
ConstantFP *CFP = dyn_cast<ConstantFP>(I->getOperand(0));
|
||||||
if (CFP && CFP->isExactlyValue(0.5)) {
|
if (CFP && CFP->isExactlyValue(0.5)) {
|
||||||
Y = I->getOperand(1);
|
Y = I->getOperand(1);
|
||||||
@ -289,14 +289,14 @@ static void detectLog2OfHalf(Value *&Op, Value *&Y, IntrinsicInst *&Log2) {
|
|||||||
CFP = dyn_cast<ConstantFP>(I->getOperand(1));
|
CFP = dyn_cast<ConstantFP>(I->getOperand(1));
|
||||||
if (CFP && CFP->isExactlyValue(0.5))
|
if (CFP && CFP->isExactlyValue(0.5))
|
||||||
Y = I->getOperand(0);
|
Y = I->getOperand(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function of InstCombiner::visitFMul(BinaryOperator(). It returns
|
/// Helper function of InstCombiner::visitFMul(BinaryOperator(). It returns
|
||||||
/// true iff the given value is FMul or FDiv with one and only one operand
|
/// true iff the given value is FMul or FDiv with one and only one operand
|
||||||
/// being a normal constant (i.e. not Zero/NaN/Infinity).
|
/// being a normal constant (i.e. not Zero/NaN/Infinity).
|
||||||
static bool isFMulOrFDivWithConstant(Value *V) {
|
static bool isFMulOrFDivWithConstant(Value *V) {
|
||||||
Instruction *I = dyn_cast<Instruction>(V);
|
Instruction *I = dyn_cast<Instruction>(V);
|
||||||
if (!I || (I->getOpcode() != Instruction::FMul &&
|
if (!I || (I->getOpcode() != Instruction::FMul &&
|
||||||
I->getOpcode() != Instruction::FDiv))
|
I->getOpcode() != Instruction::FDiv))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -318,10 +318,10 @@ static bool isNormalFp(const ConstantFP *C) {
|
|||||||
/// foldFMulConst() is a helper routine of InstCombiner::visitFMul().
|
/// foldFMulConst() is a helper routine of InstCombiner::visitFMul().
|
||||||
/// The input \p FMulOrDiv is a FMul/FDiv with one and only one operand
|
/// The input \p FMulOrDiv is a FMul/FDiv with one and only one operand
|
||||||
/// being a constant (i.e. isFMulOrFDivWithConstant(FMulOrDiv) == true).
|
/// being a constant (i.e. isFMulOrFDivWithConstant(FMulOrDiv) == true).
|
||||||
/// This function is to simplify "FMulOrDiv * C" and returns the
|
/// This function is to simplify "FMulOrDiv * C" and returns the
|
||||||
/// resulting expression. Note that this function could return NULL in
|
/// resulting expression. Note that this function could return NULL in
|
||||||
/// case the constants cannot be folded into a normal floating-point.
|
/// case the constants cannot be folded into a normal floating-point.
|
||||||
///
|
///
|
||||||
Value *InstCombiner::foldFMulConst(Instruction *FMulOrDiv, ConstantFP *C,
|
Value *InstCombiner::foldFMulConst(Instruction *FMulOrDiv, ConstantFP *C,
|
||||||
Instruction *InsertBefore) {
|
Instruction *InsertBefore) {
|
||||||
assert(isFMulOrFDivWithConstant(FMulOrDiv) && "V is invalid");
|
assert(isFMulOrFDivWithConstant(FMulOrDiv) && "V is invalid");
|
||||||
@ -351,7 +351,7 @@ Value *InstCombiner::foldFMulConst(Instruction *FMulOrDiv, ConstantFP *C,
|
|||||||
if (isNormalFp(F)) {
|
if (isNormalFp(F)) {
|
||||||
R = BinaryOperator::CreateFMul(Opnd0, F);
|
R = BinaryOperator::CreateFMul(Opnd0, F);
|
||||||
} else {
|
} else {
|
||||||
// (X / C1) * C => X / (C1/C)
|
// (X / C1) * C => X / (C1/C)
|
||||||
Constant *F = ConstantExpr::getFDiv(C1, C);
|
Constant *F = ConstantExpr::getFDiv(C1, C);
|
||||||
if (isNormalFp(cast<ConstantFP>(F)))
|
if (isNormalFp(cast<ConstantFP>(F)))
|
||||||
R = BinaryOperator::CreateFDiv(Opnd0, F);
|
R = BinaryOperator::CreateFDiv(Opnd0, F);
|
||||||
@ -415,13 +415,13 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) {
|
|||||||
if (C0) {
|
if (C0) {
|
||||||
std::swap(C0, C1);
|
std::swap(C0, C1);
|
||||||
std::swap(Opnd0, Opnd1);
|
std::swap(Opnd0, Opnd1);
|
||||||
Swap = true;
|
Swap = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (C1 && C1->getValueAPF().isNormal() &&
|
if (C1 && C1->getValueAPF().isNormal() &&
|
||||||
isFMulOrFDivWithConstant(Opnd0)) {
|
isFMulOrFDivWithConstant(Opnd0)) {
|
||||||
Value *M1 = ConstantExpr::getFMul(C1, C);
|
Value *M1 = ConstantExpr::getFMul(C1, C);
|
||||||
Value *M0 = isNormalFp(cast<ConstantFP>(M1)) ?
|
Value *M0 = isNormalFp(cast<ConstantFP>(M1)) ?
|
||||||
foldFMulConst(cast<Instruction>(Opnd0), C, &I) :
|
foldFMulConst(cast<Instruction>(Opnd0), C, &I) :
|
||||||
0;
|
0;
|
||||||
if (M0 && M1) {
|
if (M0 && M1) {
|
||||||
@ -495,7 +495,7 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// (X*Y) * X => (X*X) * Y where Y != X
|
// (X*Y) * X => (X*X) * Y where Y != X
|
||||||
// The purpose is two-fold:
|
// The purpose is two-fold:
|
||||||
// 1) to form a power expression (of X).
|
// 1) to form a power expression (of X).
|
||||||
// 2) potentially shorten the critical path: After transformation, the
|
// 2) potentially shorten the critical path: After transformation, the
|
||||||
// latency of the instruction Y is amortized by the expression of X*X,
|
// latency of the instruction Y is amortized by the expression of X*X,
|
||||||
@ -537,7 +537,7 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) {
|
|||||||
/// instruction.
|
/// instruction.
|
||||||
bool InstCombiner::SimplifyDivRemOfSelect(BinaryOperator &I) {
|
bool InstCombiner::SimplifyDivRemOfSelect(BinaryOperator &I) {
|
||||||
SelectInst *SI = cast<SelectInst>(I.getOperand(1));
|
SelectInst *SI = cast<SelectInst>(I.getOperand(1));
|
||||||
|
|
||||||
// div/rem X, (Cond ? 0 : Y) -> div/rem X, Y
|
// div/rem X, (Cond ? 0 : Y) -> div/rem X, Y
|
||||||
int NonNullOperand = -1;
|
int NonNullOperand = -1;
|
||||||
if (Constant *ST = dyn_cast<Constant>(SI->getOperand(1)))
|
if (Constant *ST = dyn_cast<Constant>(SI->getOperand(1)))
|
||||||
@ -547,36 +547,36 @@ bool InstCombiner::SimplifyDivRemOfSelect(BinaryOperator &I) {
|
|||||||
if (Constant *ST = dyn_cast<Constant>(SI->getOperand(2)))
|
if (Constant *ST = dyn_cast<Constant>(SI->getOperand(2)))
|
||||||
if (ST->isNullValue())
|
if (ST->isNullValue())
|
||||||
NonNullOperand = 1;
|
NonNullOperand = 1;
|
||||||
|
|
||||||
if (NonNullOperand == -1)
|
if (NonNullOperand == -1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Value *SelectCond = SI->getOperand(0);
|
Value *SelectCond = SI->getOperand(0);
|
||||||
|
|
||||||
// Change the div/rem to use 'Y' instead of the select.
|
// Change the div/rem to use 'Y' instead of the select.
|
||||||
I.setOperand(1, SI->getOperand(NonNullOperand));
|
I.setOperand(1, SI->getOperand(NonNullOperand));
|
||||||
|
|
||||||
// Okay, we know we replace the operand of the div/rem with 'Y' with no
|
// Okay, we know we replace the operand of the div/rem with 'Y' with no
|
||||||
// problem. However, the select, or the condition of the select may have
|
// problem. However, the select, or the condition of the select may have
|
||||||
// multiple uses. Based on our knowledge that the operand must be non-zero,
|
// multiple uses. Based on our knowledge that the operand must be non-zero,
|
||||||
// propagate the known value for the select into other uses of it, and
|
// propagate the known value for the select into other uses of it, and
|
||||||
// propagate a known value of the condition into its other users.
|
// propagate a known value of the condition into its other users.
|
||||||
|
|
||||||
// If the select and condition only have a single use, don't bother with this,
|
// If the select and condition only have a single use, don't bother with this,
|
||||||
// early exit.
|
// early exit.
|
||||||
if (SI->use_empty() && SelectCond->hasOneUse())
|
if (SI->use_empty() && SelectCond->hasOneUse())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Scan the current block backward, looking for other uses of SI.
|
// Scan the current block backward, looking for other uses of SI.
|
||||||
BasicBlock::iterator BBI = &I, BBFront = I.getParent()->begin();
|
BasicBlock::iterator BBI = &I, BBFront = I.getParent()->begin();
|
||||||
|
|
||||||
while (BBI != BBFront) {
|
while (BBI != BBFront) {
|
||||||
--BBI;
|
--BBI;
|
||||||
// If we found a call to a function, we can't assume it will return, so
|
// If we found a call to a function, we can't assume it will return, so
|
||||||
// information from below it cannot be propagated above it.
|
// information from below it cannot be propagated above it.
|
||||||
if (isa<CallInst>(BBI) && !isa<IntrinsicInst>(BBI))
|
if (isa<CallInst>(BBI) && !isa<IntrinsicInst>(BBI))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Replace uses of the select or its condition with the known values.
|
// Replace uses of the select or its condition with the known values.
|
||||||
for (Instruction::op_iterator I = BBI->op_begin(), E = BBI->op_end();
|
for (Instruction::op_iterator I = BBI->op_begin(), E = BBI->op_end();
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
@ -589,17 +589,17 @@ bool InstCombiner::SimplifyDivRemOfSelect(BinaryOperator &I) {
|
|||||||
Worklist.Add(BBI);
|
Worklist.Add(BBI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we past the instruction, quit looking for it.
|
// If we past the instruction, quit looking for it.
|
||||||
if (&*BBI == SI)
|
if (&*BBI == SI)
|
||||||
SI = 0;
|
SI = 0;
|
||||||
if (&*BBI == SelectCond)
|
if (&*BBI == SelectCond)
|
||||||
SelectCond = 0;
|
SelectCond = 0;
|
||||||
|
|
||||||
// If we ran out of things to eliminate, break out of the loop.
|
// If we ran out of things to eliminate, break out of the loop.
|
||||||
if (SelectCond == 0 && SI == 0)
|
if (SelectCond == 0 && SI == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -617,7 +617,7 @@ Instruction *InstCombiner::commonIDivTransforms(BinaryOperator &I) {
|
|||||||
I.setOperand(1, V);
|
I.setOperand(1, V);
|
||||||
return &I;
|
return &I;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle cases involving: [su]div X, (select Cond, Y, Z)
|
// Handle cases involving: [su]div X, (select Cond, Y, Z)
|
||||||
// This does not apply for fdiv.
|
// This does not apply for fdiv.
|
||||||
if (isa<SelectInst>(Op1) && SimplifyDivRemOfSelect(I))
|
if (isa<SelectInst>(Op1) && SimplifyDivRemOfSelect(I))
|
||||||
@ -683,16 +683,16 @@ Instruction *InstCombiner::visitUDiv(BinaryOperator &I) {
|
|||||||
// Handle the integer div common cases
|
// Handle the integer div common cases
|
||||||
if (Instruction *Common = commonIDivTransforms(I))
|
if (Instruction *Common = commonIDivTransforms(I))
|
||||||
return Common;
|
return Common;
|
||||||
|
|
||||||
{
|
{
|
||||||
// X udiv 2^C -> X >> C
|
// X udiv 2^C -> X >> C
|
||||||
// Check to see if this is an unsigned division with an exact power of 2,
|
// Check to see if this is an unsigned division with an exact power of 2,
|
||||||
// if so, convert to a right shift.
|
// if so, convert to a right shift.
|
||||||
const APInt *C;
|
const APInt *C;
|
||||||
if (match(Op1, m_Power2(C))) {
|
if (match(Op1, m_Power2(C))) {
|
||||||
BinaryOperator *LShr =
|
BinaryOperator *LShr =
|
||||||
BinaryOperator::CreateLShr(Op0,
|
BinaryOperator::CreateLShr(Op0,
|
||||||
ConstantInt::get(Op0->getType(),
|
ConstantInt::get(Op0->getType(),
|
||||||
C->logBase2()));
|
C->logBase2()));
|
||||||
if (I.isExact()) LShr->setIsExact();
|
if (I.isExact()) LShr->setIsExact();
|
||||||
return LShr;
|
return LShr;
|
||||||
@ -732,7 +732,7 @@ Instruction *InstCombiner::visitUDiv(BinaryOperator &I) {
|
|||||||
return BinaryOperator::CreateLShr(Op0, N);
|
return BinaryOperator::CreateLShr(Op0, N);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// udiv X, (Select Cond, C1, C2) --> Select Cond, (shr X, C1), (shr X, C2)
|
// udiv X, (Select Cond, C1, C2) --> Select Cond, (shr X, C1), (shr X, C2)
|
||||||
// where C1&C2 are powers of two.
|
// where C1&C2 are powers of two.
|
||||||
{ Value *Cond; const APInt *C1, *C2;
|
{ Value *Cond; const APInt *C1, *C2;
|
||||||
@ -740,11 +740,11 @@ Instruction *InstCombiner::visitUDiv(BinaryOperator &I) {
|
|||||||
// Construct the "on true" case of the select
|
// Construct the "on true" case of the select
|
||||||
Value *TSI = Builder->CreateLShr(Op0, C1->logBase2(), Op1->getName()+".t",
|
Value *TSI = Builder->CreateLShr(Op0, C1->logBase2(), Op1->getName()+".t",
|
||||||
I.isExact());
|
I.isExact());
|
||||||
|
|
||||||
// Construct the "on false" case of the select
|
// Construct the "on false" case of the select
|
||||||
Value *FSI = Builder->CreateLShr(Op0, C2->logBase2(), Op1->getName()+".f",
|
Value *FSI = Builder->CreateLShr(Op0, C2->logBase2(), Op1->getName()+".f",
|
||||||
I.isExact());
|
I.isExact());
|
||||||
|
|
||||||
// construct the select instruction and return it.
|
// construct the select instruction and return it.
|
||||||
return SelectInst::Create(Cond, TSI, FSI);
|
return SelectInst::Create(Cond, TSI, FSI);
|
||||||
}
|
}
|
||||||
@ -799,7 +799,7 @@ Instruction *InstCombiner::visitSDiv(BinaryOperator &I) {
|
|||||||
// X sdiv Y -> X udiv Y, iff X and Y don't have sign bit set
|
// X sdiv Y -> X udiv Y, iff X and Y don't have sign bit set
|
||||||
return BinaryOperator::CreateUDiv(Op0, Op1, I.getName());
|
return BinaryOperator::CreateUDiv(Op0, Op1, I.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match(Op1, m_Shl(m_Power2(), m_Value()))) {
|
if (match(Op1, m_Shl(m_Power2(), m_Value()))) {
|
||||||
// X sdiv (1 << Y) -> X udiv (1 << Y) ( -> X u>> Y)
|
// X sdiv (1 << Y) -> X udiv (1 << Y) ( -> X u>> Y)
|
||||||
// Safe because the only negative value (1 << Y) can take on is
|
// Safe because the only negative value (1 << Y) can take on is
|
||||||
@ -809,13 +809,13 @@ Instruction *InstCombiner::visitSDiv(BinaryOperator &I) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// CvtFDivConstToReciprocal tries to convert X/C into X*1/C if C not a special
|
/// CvtFDivConstToReciprocal tries to convert X/C into X*1/C if C not a special
|
||||||
/// FP value and:
|
/// FP value and:
|
||||||
/// 1) 1/C is exact, or
|
/// 1) 1/C is exact, or
|
||||||
/// 2) reciprocal is allowed.
|
/// 2) reciprocal is allowed.
|
||||||
/// If the convertion was successful, the simplified expression "X * 1/C" is
|
/// If the convertion was successful, the simplified expression "X * 1/C" is
|
||||||
/// returned; otherwise, NULL is returned.
|
/// returned; otherwise, NULL is returned.
|
||||||
@ -826,7 +826,7 @@ static Instruction *CvtFDivConstToReciprocal(Value *Dividend,
|
|||||||
const APFloat &FpVal = Divisor->getValueAPF();
|
const APFloat &FpVal = Divisor->getValueAPF();
|
||||||
APFloat Reciprocal(FpVal.getSemantics());
|
APFloat Reciprocal(FpVal.getSemantics());
|
||||||
bool Cvt = FpVal.getExactInverse(&Reciprocal);
|
bool Cvt = FpVal.getExactInverse(&Reciprocal);
|
||||||
|
|
||||||
if (!Cvt && AllowReciprocal && FpVal.isNormal()) {
|
if (!Cvt && AllowReciprocal && FpVal.isNormal()) {
|
||||||
Reciprocal = APFloat(FpVal.getSemantics(), 1.0f);
|
Reciprocal = APFloat(FpVal.getSemantics(), 1.0f);
|
||||||
(void)Reciprocal.divide(FpVal, APFloat::rmNearestTiesToEven);
|
(void)Reciprocal.divide(FpVal, APFloat::rmNearestTiesToEven);
|
||||||
@ -870,10 +870,10 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) {
|
|||||||
Constant *C = ConstantExpr::getFMul(C1, C2);
|
Constant *C = ConstantExpr::getFMul(C1, C2);
|
||||||
const APFloat &F = cast<ConstantFP>(C)->getValueAPF();
|
const APFloat &F = cast<ConstantFP>(C)->getValueAPF();
|
||||||
if (F.isNormal() && !F.isDenormal()) {
|
if (F.isNormal() && !F.isDenormal()) {
|
||||||
Res = CvtFDivConstToReciprocal(X, cast<ConstantFP>(C),
|
Res = CvtFDivConstToReciprocal(X, cast<ConstantFP>(C),
|
||||||
AllowReciprocal);
|
AllowReciprocal);
|
||||||
if (!Res)
|
if (!Res)
|
||||||
Res = BinaryOperator::CreateFDiv(X, C);
|
Res = BinaryOperator::CreateFDiv(X, C);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -911,7 +911,7 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) {
|
|||||||
if (Fold) {
|
if (Fold) {
|
||||||
const APFloat &FoldC = cast<ConstantFP>(Fold)->getValueAPF();
|
const APFloat &FoldC = cast<ConstantFP>(Fold)->getValueAPF();
|
||||||
if (FoldC.isNormal() && !FoldC.isDenormal()) {
|
if (FoldC.isNormal() && !FoldC.isDenormal()) {
|
||||||
Instruction *R = CreateDiv ?
|
Instruction *R = CreateDiv ?
|
||||||
BinaryOperator::CreateFDiv(Fold, X) :
|
BinaryOperator::CreateFDiv(Fold, X) :
|
||||||
BinaryOperator::CreateFMul(X, Fold);
|
BinaryOperator::CreateFMul(X, Fold);
|
||||||
R->setFastMathFlags(I.getFastMathFlags());
|
R->setFastMathFlags(I.getFastMathFlags());
|
||||||
@ -997,7 +997,7 @@ Instruction *InstCombiner::visitURem(BinaryOperator &I) {
|
|||||||
|
|
||||||
if (Instruction *common = commonIRemTransforms(I))
|
if (Instruction *common = commonIRemTransforms(I))
|
||||||
return common;
|
return common;
|
||||||
|
|
||||||
// X urem C^2 -> X and C-1
|
// X urem C^2 -> X and C-1
|
||||||
{ const APInt *C;
|
{ const APInt *C;
|
||||||
if (match(Op1, m_Power2(C)))
|
if (match(Op1, m_Power2(C)))
|
||||||
@ -1005,7 +1005,7 @@ Instruction *InstCombiner::visitURem(BinaryOperator &I) {
|
|||||||
ConstantInt::get(I.getType(), *C-1));
|
ConstantInt::get(I.getType(), *C-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Turn A % (C << N), where C is 2^k, into A & ((C << N)-1)
|
// Turn A % (C << N), where C is 2^k, into A & ((C << N)-1)
|
||||||
if (match(Op1, m_Shl(m_Power2(), m_Value()))) {
|
if (match(Op1, m_Shl(m_Power2(), m_Value()))) {
|
||||||
Constant *N1 = Constant::getAllOnesValue(I.getType());
|
Constant *N1 = Constant::getAllOnesValue(I.getType());
|
||||||
Value *Add = Builder->CreateAdd(Op1, N1);
|
Value *Add = Builder->CreateAdd(Op1, N1);
|
||||||
@ -1041,7 +1041,7 @@ Instruction *InstCombiner::visitSRem(BinaryOperator &I) {
|
|||||||
// Handle the integer rem common cases
|
// Handle the integer rem common cases
|
||||||
if (Instruction *Common = commonIRemTransforms(I))
|
if (Instruction *Common = commonIRemTransforms(I))
|
||||||
return Common;
|
return Common;
|
||||||
|
|
||||||
if (Value *RHSNeg = dyn_castNegVal(Op1))
|
if (Value *RHSNeg = dyn_castNegVal(Op1))
|
||||||
if (!isa<Constant>(RHSNeg) ||
|
if (!isa<Constant>(RHSNeg) ||
|
||||||
(isa<ConstantInt>(RHSNeg) &&
|
(isa<ConstantInt>(RHSNeg) &&
|
||||||
|
@ -27,10 +27,10 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
|
|||||||
unsigned Opc = FirstInst->getOpcode();
|
unsigned Opc = FirstInst->getOpcode();
|
||||||
Value *LHSVal = FirstInst->getOperand(0);
|
Value *LHSVal = FirstInst->getOperand(0);
|
||||||
Value *RHSVal = FirstInst->getOperand(1);
|
Value *RHSVal = FirstInst->getOperand(1);
|
||||||
|
|
||||||
Type *LHSType = LHSVal->getType();
|
Type *LHSType = LHSVal->getType();
|
||||||
Type *RHSType = RHSVal->getType();
|
Type *RHSType = RHSVal->getType();
|
||||||
|
|
||||||
bool isNUW = false, isNSW = false, isExact = false;
|
bool isNUW = false, isNSW = false, isExact = false;
|
||||||
if (OverflowingBinaryOperator *BO =
|
if (OverflowingBinaryOperator *BO =
|
||||||
dyn_cast<OverflowingBinaryOperator>(FirstInst)) {
|
dyn_cast<OverflowingBinaryOperator>(FirstInst)) {
|
||||||
@ -39,7 +39,7 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
|
|||||||
} else if (PossiblyExactOperator *PEO =
|
} else if (PossiblyExactOperator *PEO =
|
||||||
dyn_cast<PossiblyExactOperator>(FirstInst))
|
dyn_cast<PossiblyExactOperator>(FirstInst))
|
||||||
isExact = PEO->isExact();
|
isExact = PEO->isExact();
|
||||||
|
|
||||||
// Scan to see if all operands are the same opcode, and all have one use.
|
// Scan to see if all operands are the same opcode, and all have one use.
|
||||||
for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) {
|
for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) {
|
||||||
Instruction *I = dyn_cast<Instruction>(PN.getIncomingValue(i));
|
Instruction *I = dyn_cast<Instruction>(PN.getIncomingValue(i));
|
||||||
@ -54,14 +54,14 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
|
|||||||
if (CmpInst *CI = dyn_cast<CmpInst>(I))
|
if (CmpInst *CI = dyn_cast<CmpInst>(I))
|
||||||
if (CI->getPredicate() != cast<CmpInst>(FirstInst)->getPredicate())
|
if (CI->getPredicate() != cast<CmpInst>(FirstInst)->getPredicate())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (isNUW)
|
if (isNUW)
|
||||||
isNUW = cast<OverflowingBinaryOperator>(I)->hasNoUnsignedWrap();
|
isNUW = cast<OverflowingBinaryOperator>(I)->hasNoUnsignedWrap();
|
||||||
if (isNSW)
|
if (isNSW)
|
||||||
isNSW = cast<OverflowingBinaryOperator>(I)->hasNoSignedWrap();
|
isNSW = cast<OverflowingBinaryOperator>(I)->hasNoSignedWrap();
|
||||||
if (isExact)
|
if (isExact)
|
||||||
isExact = cast<PossiblyExactOperator>(I)->isExact();
|
isExact = cast<PossiblyExactOperator>(I)->isExact();
|
||||||
|
|
||||||
// Keep track of which operand needs a phi node.
|
// Keep track of which operand needs a phi node.
|
||||||
if (I->getOperand(0) != LHSVal) LHSVal = 0;
|
if (I->getOperand(0) != LHSVal) LHSVal = 0;
|
||||||
if (I->getOperand(1) != RHSVal) RHSVal = 0;
|
if (I->getOperand(1) != RHSVal) RHSVal = 0;
|
||||||
@ -73,9 +73,9 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
|
|||||||
// bad when the PHIs are in the header of a loop.
|
// bad when the PHIs are in the header of a loop.
|
||||||
if (!LHSVal && !RHSVal)
|
if (!LHSVal && !RHSVal)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Otherwise, this is safe to transform!
|
// Otherwise, this is safe to transform!
|
||||||
|
|
||||||
Value *InLHS = FirstInst->getOperand(0);
|
Value *InLHS = FirstInst->getOperand(0);
|
||||||
Value *InRHS = FirstInst->getOperand(1);
|
Value *InRHS = FirstInst->getOperand(1);
|
||||||
PHINode *NewLHS = 0, *NewRHS = 0;
|
PHINode *NewLHS = 0, *NewRHS = 0;
|
||||||
@ -86,7 +86,7 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
|
|||||||
InsertNewInstBefore(NewLHS, PN);
|
InsertNewInstBefore(NewLHS, PN);
|
||||||
LHSVal = NewLHS;
|
LHSVal = NewLHS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RHSVal == 0) {
|
if (RHSVal == 0) {
|
||||||
NewRHS = PHINode::Create(RHSType, PN.getNumIncomingValues(),
|
NewRHS = PHINode::Create(RHSType, PN.getNumIncomingValues(),
|
||||||
FirstInst->getOperand(1)->getName() + ".pn");
|
FirstInst->getOperand(1)->getName() + ".pn");
|
||||||
@ -94,7 +94,7 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
|
|||||||
InsertNewInstBefore(NewRHS, PN);
|
InsertNewInstBefore(NewRHS, PN);
|
||||||
RHSVal = NewRHS;
|
RHSVal = NewRHS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add all operands to the new PHIs.
|
// Add all operands to the new PHIs.
|
||||||
if (NewLHS || NewRHS) {
|
if (NewLHS || NewRHS) {
|
||||||
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
|
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
|
||||||
@ -109,7 +109,7 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CmpInst *CIOp = dyn_cast<CmpInst>(FirstInst)) {
|
if (CmpInst *CIOp = dyn_cast<CmpInst>(FirstInst)) {
|
||||||
CmpInst *NewCI = CmpInst::Create(CIOp->getOpcode(), CIOp->getPredicate(),
|
CmpInst *NewCI = CmpInst::Create(CIOp->getOpcode(), CIOp->getPredicate(),
|
||||||
LHSVal, RHSVal);
|
LHSVal, RHSVal);
|
||||||
@ -129,8 +129,8 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
|
|||||||
|
|
||||||
Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
|
Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
|
||||||
GetElementPtrInst *FirstInst =cast<GetElementPtrInst>(PN.getIncomingValue(0));
|
GetElementPtrInst *FirstInst =cast<GetElementPtrInst>(PN.getIncomingValue(0));
|
||||||
|
|
||||||
SmallVector<Value*, 16> FixedOperands(FirstInst->op_begin(),
|
SmallVector<Value*, 16> FixedOperands(FirstInst->op_begin(),
|
||||||
FirstInst->op_end());
|
FirstInst->op_end());
|
||||||
// This is true if all GEP bases are allocas and if all indices into them are
|
// This is true if all GEP bases are allocas and if all indices into them are
|
||||||
// constants.
|
// constants.
|
||||||
@ -140,9 +140,9 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
|
|||||||
// more than one phi, which leads to higher register pressure. This is
|
// more than one phi, which leads to higher register pressure. This is
|
||||||
// especially bad when the PHIs are in the header of a loop.
|
// especially bad when the PHIs are in the header of a loop.
|
||||||
bool NeededPhi = false;
|
bool NeededPhi = false;
|
||||||
|
|
||||||
bool AllInBounds = true;
|
bool AllInBounds = true;
|
||||||
|
|
||||||
// Scan to see if all operands are the same opcode, and all have one use.
|
// Scan to see if all operands are the same opcode, and all have one use.
|
||||||
for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) {
|
for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) {
|
||||||
GetElementPtrInst *GEP= dyn_cast<GetElementPtrInst>(PN.getIncomingValue(i));
|
GetElementPtrInst *GEP= dyn_cast<GetElementPtrInst>(PN.getIncomingValue(i));
|
||||||
@ -151,18 +151,18 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
AllInBounds &= GEP->isInBounds();
|
AllInBounds &= GEP->isInBounds();
|
||||||
|
|
||||||
// Keep track of whether or not all GEPs are of alloca pointers.
|
// Keep track of whether or not all GEPs are of alloca pointers.
|
||||||
if (AllBasePointersAreAllocas &&
|
if (AllBasePointersAreAllocas &&
|
||||||
(!isa<AllocaInst>(GEP->getOperand(0)) ||
|
(!isa<AllocaInst>(GEP->getOperand(0)) ||
|
||||||
!GEP->hasAllConstantIndices()))
|
!GEP->hasAllConstantIndices()))
|
||||||
AllBasePointersAreAllocas = false;
|
AllBasePointersAreAllocas = false;
|
||||||
|
|
||||||
// Compare the operand lists.
|
// Compare the operand lists.
|
||||||
for (unsigned op = 0, e = FirstInst->getNumOperands(); op != e; ++op) {
|
for (unsigned op = 0, e = FirstInst->getNumOperands(); op != e; ++op) {
|
||||||
if (FirstInst->getOperand(op) == GEP->getOperand(op))
|
if (FirstInst->getOperand(op) == GEP->getOperand(op))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Don't merge two GEPs when two operands differ (introducing phi nodes)
|
// Don't merge two GEPs when two operands differ (introducing phi nodes)
|
||||||
// if one of the PHIs has a constant for the index. The index may be
|
// if one of the PHIs has a constant for the index. The index may be
|
||||||
// substantially cheaper to compute for the constants, so making it a
|
// substantially cheaper to compute for the constants, so making it a
|
||||||
@ -171,7 +171,7 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
|
|||||||
if (isa<ConstantInt>(FirstInst->getOperand(op)) ||
|
if (isa<ConstantInt>(FirstInst->getOperand(op)) ||
|
||||||
isa<ConstantInt>(GEP->getOperand(op)))
|
isa<ConstantInt>(GEP->getOperand(op)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (FirstInst->getOperand(op)->getType() !=GEP->getOperand(op)->getType())
|
if (FirstInst->getOperand(op)->getType() !=GEP->getOperand(op)->getType())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
|
|||||||
NeededPhi = true;
|
NeededPhi = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If all of the base pointers of the PHI'd GEPs are from allocas, don't
|
// If all of the base pointers of the PHI'd GEPs are from allocas, don't
|
||||||
// bother doing this transformation. At best, this will just save a bit of
|
// bother doing this transformation. At best, this will just save a bit of
|
||||||
// offset calculation, but all the predecessors will have to materialize the
|
// offset calculation, but all the predecessors will have to materialize the
|
||||||
@ -195,11 +195,11 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
|
|||||||
// which can usually all be folded into the load.
|
// which can usually all be folded into the load.
|
||||||
if (AllBasePointersAreAllocas)
|
if (AllBasePointersAreAllocas)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Otherwise, this is safe to transform. Insert PHI nodes for each operand
|
// Otherwise, this is safe to transform. Insert PHI nodes for each operand
|
||||||
// that is variable.
|
// that is variable.
|
||||||
SmallVector<PHINode*, 16> OperandPhis(FixedOperands.size());
|
SmallVector<PHINode*, 16> OperandPhis(FixedOperands.size());
|
||||||
|
|
||||||
bool HasAnyPHIs = false;
|
bool HasAnyPHIs = false;
|
||||||
for (unsigned i = 0, e = FixedOperands.size(); i != e; ++i) {
|
for (unsigned i = 0, e = FixedOperands.size(); i != e; ++i) {
|
||||||
if (FixedOperands[i]) continue; // operand doesn't need a phi.
|
if (FixedOperands[i]) continue; // operand doesn't need a phi.
|
||||||
@ -207,28 +207,28 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
|
|||||||
PHINode *NewPN = PHINode::Create(FirstOp->getType(), e,
|
PHINode *NewPN = PHINode::Create(FirstOp->getType(), e,
|
||||||
FirstOp->getName()+".pn");
|
FirstOp->getName()+".pn");
|
||||||
InsertNewInstBefore(NewPN, PN);
|
InsertNewInstBefore(NewPN, PN);
|
||||||
|
|
||||||
NewPN->addIncoming(FirstOp, PN.getIncomingBlock(0));
|
NewPN->addIncoming(FirstOp, PN.getIncomingBlock(0));
|
||||||
OperandPhis[i] = NewPN;
|
OperandPhis[i] = NewPN;
|
||||||
FixedOperands[i] = NewPN;
|
FixedOperands[i] = NewPN;
|
||||||
HasAnyPHIs = true;
|
HasAnyPHIs = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Add all operands to the new PHIs.
|
// Add all operands to the new PHIs.
|
||||||
if (HasAnyPHIs) {
|
if (HasAnyPHIs) {
|
||||||
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
|
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
|
||||||
GetElementPtrInst *InGEP =cast<GetElementPtrInst>(PN.getIncomingValue(i));
|
GetElementPtrInst *InGEP =cast<GetElementPtrInst>(PN.getIncomingValue(i));
|
||||||
BasicBlock *InBB = PN.getIncomingBlock(i);
|
BasicBlock *InBB = PN.getIncomingBlock(i);
|
||||||
|
|
||||||
for (unsigned op = 0, e = OperandPhis.size(); op != e; ++op)
|
for (unsigned op = 0, e = OperandPhis.size(); op != e; ++op)
|
||||||
if (PHINode *OpPhi = OperandPhis[op])
|
if (PHINode *OpPhi = OperandPhis[op])
|
||||||
OpPhi->addIncoming(InGEP->getOperand(op), InBB);
|
OpPhi->addIncoming(InGEP->getOperand(op), InBB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *Base = FixedOperands[0];
|
Value *Base = FixedOperands[0];
|
||||||
GetElementPtrInst *NewGEP =
|
GetElementPtrInst *NewGEP =
|
||||||
GetElementPtrInst::Create(Base, makeArrayRef(FixedOperands).slice(1));
|
GetElementPtrInst::Create(Base, makeArrayRef(FixedOperands).slice(1));
|
||||||
if (AllInBounds) NewGEP->setIsInBounds();
|
if (AllInBounds) NewGEP->setIsInBounds();
|
||||||
NewGEP->setDebugLoc(FirstInst->getDebugLoc());
|
NewGEP->setDebugLoc(FirstInst->getDebugLoc());
|
||||||
@ -246,11 +246,11 @@ Instruction *InstCombiner::FoldPHIArgGEPIntoPHI(PHINode &PN) {
|
|||||||
/// to a register.
|
/// to a register.
|
||||||
static bool isSafeAndProfitableToSinkLoad(LoadInst *L) {
|
static bool isSafeAndProfitableToSinkLoad(LoadInst *L) {
|
||||||
BasicBlock::iterator BBI = L, E = L->getParent()->end();
|
BasicBlock::iterator BBI = L, E = L->getParent()->end();
|
||||||
|
|
||||||
for (++BBI; BBI != E; ++BBI)
|
for (++BBI; BBI != E; ++BBI)
|
||||||
if (BBI->mayWriteToMemory())
|
if (BBI->mayWriteToMemory())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check for non-address taken alloca. If not address-taken already, it isn't
|
// Check for non-address taken alloca. If not address-taken already, it isn't
|
||||||
// profitable to do this xform.
|
// profitable to do this xform.
|
||||||
if (AllocaInst *AI = dyn_cast<AllocaInst>(L->getOperand(0))) {
|
if (AllocaInst *AI = dyn_cast<AllocaInst>(L->getOperand(0))) {
|
||||||
@ -266,11 +266,11 @@ static bool isSafeAndProfitableToSinkLoad(LoadInst *L) {
|
|||||||
isAddressTaken = true;
|
isAddressTaken = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isAddressTaken && AI->isStaticAlloca())
|
if (!isAddressTaken && AI->isStaticAlloca())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this load is a load from a GEP with a constant offset from an alloca,
|
// If this load is a load from a GEP with a constant offset from an alloca,
|
||||||
// then we don't want to sink it. In its present form, it will be
|
// then we don't want to sink it. In its present form, it will be
|
||||||
// load [constant stack offset]. Sinking it will cause us to have to
|
// load [constant stack offset]. Sinking it will cause us to have to
|
||||||
@ -280,7 +280,7 @@ static bool isSafeAndProfitableToSinkLoad(LoadInst *L) {
|
|||||||
if (AllocaInst *AI = dyn_cast<AllocaInst>(GEP->getOperand(0)))
|
if (AllocaInst *AI = dyn_cast<AllocaInst>(GEP->getOperand(0)))
|
||||||
if (AI->isStaticAlloca() && GEP->hasAllConstantIndices())
|
if (AI->isStaticAlloca() && GEP->hasAllConstantIndices())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,41 +300,41 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) {
|
|||||||
bool isVolatile = FirstLI->isVolatile();
|
bool isVolatile = FirstLI->isVolatile();
|
||||||
unsigned LoadAlignment = FirstLI->getAlignment();
|
unsigned LoadAlignment = FirstLI->getAlignment();
|
||||||
unsigned LoadAddrSpace = FirstLI->getPointerAddressSpace();
|
unsigned LoadAddrSpace = FirstLI->getPointerAddressSpace();
|
||||||
|
|
||||||
// We can't sink the load if the loaded value could be modified between the
|
// We can't sink the load if the loaded value could be modified between the
|
||||||
// load and the PHI.
|
// load and the PHI.
|
||||||
if (FirstLI->getParent() != PN.getIncomingBlock(0) ||
|
if (FirstLI->getParent() != PN.getIncomingBlock(0) ||
|
||||||
!isSafeAndProfitableToSinkLoad(FirstLI))
|
!isSafeAndProfitableToSinkLoad(FirstLI))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// If the PHI is of volatile loads and the load block has multiple
|
// If the PHI is of volatile loads and the load block has multiple
|
||||||
// successors, sinking it would remove a load of the volatile value from
|
// successors, sinking it would remove a load of the volatile value from
|
||||||
// the path through the other successor.
|
// the path through the other successor.
|
||||||
if (isVolatile &&
|
if (isVolatile &&
|
||||||
FirstLI->getParent()->getTerminator()->getNumSuccessors() != 1)
|
FirstLI->getParent()->getTerminator()->getNumSuccessors() != 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Check to see if all arguments are the same operation.
|
// Check to see if all arguments are the same operation.
|
||||||
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
|
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
|
||||||
LoadInst *LI = dyn_cast<LoadInst>(PN.getIncomingValue(i));
|
LoadInst *LI = dyn_cast<LoadInst>(PN.getIncomingValue(i));
|
||||||
if (!LI || !LI->hasOneUse())
|
if (!LI || !LI->hasOneUse())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// We can't sink the load if the loaded value could be modified between
|
// We can't sink the load if the loaded value could be modified between
|
||||||
// the load and the PHI.
|
// the load and the PHI.
|
||||||
if (LI->isVolatile() != isVolatile ||
|
if (LI->isVolatile() != isVolatile ||
|
||||||
LI->getParent() != PN.getIncomingBlock(i) ||
|
LI->getParent() != PN.getIncomingBlock(i) ||
|
||||||
LI->getPointerAddressSpace() != LoadAddrSpace ||
|
LI->getPointerAddressSpace() != LoadAddrSpace ||
|
||||||
!isSafeAndProfitableToSinkLoad(LI))
|
!isSafeAndProfitableToSinkLoad(LI))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// If some of the loads have an alignment specified but not all of them,
|
// If some of the loads have an alignment specified but not all of them,
|
||||||
// we can't do the transformation.
|
// we can't do the transformation.
|
||||||
if ((LoadAlignment != 0) != (LI->getAlignment() != 0))
|
if ((LoadAlignment != 0) != (LI->getAlignment() != 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
LoadAlignment = std::min(LoadAlignment, LI->getAlignment());
|
LoadAlignment = std::min(LoadAlignment, LI->getAlignment());
|
||||||
|
|
||||||
// If the PHI is of volatile loads and the load block has multiple
|
// If the PHI is of volatile loads and the load block has multiple
|
||||||
// successors, sinking it would remove a load of the volatile value from
|
// successors, sinking it would remove a load of the volatile value from
|
||||||
// the path through the other successor.
|
// the path through the other successor.
|
||||||
@ -342,16 +342,16 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) {
|
|||||||
LI->getParent()->getTerminator()->getNumSuccessors() != 1)
|
LI->getParent()->getTerminator()->getNumSuccessors() != 1)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Okay, they are all the same operation. Create a new PHI node of the
|
// Okay, they are all the same operation. Create a new PHI node of the
|
||||||
// correct type, and PHI together all of the LHS's of the instructions.
|
// correct type, and PHI together all of the LHS's of the instructions.
|
||||||
PHINode *NewPN = PHINode::Create(FirstLI->getOperand(0)->getType(),
|
PHINode *NewPN = PHINode::Create(FirstLI->getOperand(0)->getType(),
|
||||||
PN.getNumIncomingValues(),
|
PN.getNumIncomingValues(),
|
||||||
PN.getName()+".in");
|
PN.getName()+".in");
|
||||||
|
|
||||||
Value *InVal = FirstLI->getOperand(0);
|
Value *InVal = FirstLI->getOperand(0);
|
||||||
NewPN->addIncoming(InVal, PN.getIncomingBlock(0));
|
NewPN->addIncoming(InVal, PN.getIncomingBlock(0));
|
||||||
|
|
||||||
// Add all operands to the new PHI.
|
// Add all operands to the new PHI.
|
||||||
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
|
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
|
||||||
Value *NewInVal = cast<LoadInst>(PN.getIncomingValue(i))->getOperand(0);
|
Value *NewInVal = cast<LoadInst>(PN.getIncomingValue(i))->getOperand(0);
|
||||||
@ -359,7 +359,7 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) {
|
|||||||
InVal = 0;
|
InVal = 0;
|
||||||
NewPN->addIncoming(NewInVal, PN.getIncomingBlock(i));
|
NewPN->addIncoming(NewInVal, PN.getIncomingBlock(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *PhiVal;
|
Value *PhiVal;
|
||||||
if (InVal) {
|
if (InVal) {
|
||||||
// The new PHI unions all of the same values together. This is really
|
// The new PHI unions all of the same values together. This is really
|
||||||
@ -370,14 +370,14 @@ Instruction *InstCombiner::FoldPHIArgLoadIntoPHI(PHINode &PN) {
|
|||||||
InsertNewInstBefore(NewPN, PN);
|
InsertNewInstBefore(NewPN, PN);
|
||||||
PhiVal = NewPN;
|
PhiVal = NewPN;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this was a volatile load that we are merging, make sure to loop through
|
// If this was a volatile load that we are merging, make sure to loop through
|
||||||
// and mark all the input loads as non-volatile. If we don't do this, we will
|
// and mark all the input loads as non-volatile. If we don't do this, we will
|
||||||
// insert a new volatile load and the old ones will not be deletable.
|
// insert a new volatile load and the old ones will not be deletable.
|
||||||
if (isVolatile)
|
if (isVolatile)
|
||||||
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
|
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
|
||||||
cast<LoadInst>(PN.getIncomingValue(i))->setVolatile(false);
|
cast<LoadInst>(PN.getIncomingValue(i))->setVolatile(false);
|
||||||
|
|
||||||
LoadInst *NewLI = new LoadInst(PhiVal, "", isVolatile, LoadAlignment);
|
LoadInst *NewLI = new LoadInst(PhiVal, "", isVolatile, LoadAlignment);
|
||||||
NewLI->setDebugLoc(FirstLI->getDebugLoc());
|
NewLI->setDebugLoc(FirstLI->getDebugLoc());
|
||||||
return NewLI;
|
return NewLI;
|
||||||
@ -395,7 +395,7 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
|
|||||||
return FoldPHIArgGEPIntoPHI(PN);
|
return FoldPHIArgGEPIntoPHI(PN);
|
||||||
if (isa<LoadInst>(FirstInst))
|
if (isa<LoadInst>(FirstInst))
|
||||||
return FoldPHIArgLoadIntoPHI(PN);
|
return FoldPHIArgLoadIntoPHI(PN);
|
||||||
|
|
||||||
// Scan the instruction, looking for input operations that can be folded away.
|
// Scan the instruction, looking for input operations that can be folded away.
|
||||||
// If all input operands to the phi are the same instruction (e.g. a cast from
|
// If all input operands to the phi are the same instruction (e.g. a cast from
|
||||||
// the same type or "+42") we can pull the operation through the PHI, reducing
|
// the same type or "+42") we can pull the operation through the PHI, reducing
|
||||||
@ -403,7 +403,7 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
|
|||||||
Constant *ConstantOp = 0;
|
Constant *ConstantOp = 0;
|
||||||
Type *CastSrcTy = 0;
|
Type *CastSrcTy = 0;
|
||||||
bool isNUW = false, isNSW = false, isExact = false;
|
bool isNUW = false, isNSW = false, isExact = false;
|
||||||
|
|
||||||
if (isa<CastInst>(FirstInst)) {
|
if (isa<CastInst>(FirstInst)) {
|
||||||
CastSrcTy = FirstInst->getOperand(0)->getType();
|
CastSrcTy = FirstInst->getOperand(0)->getType();
|
||||||
|
|
||||||
@ -414,12 +414,12 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else if (isa<BinaryOperator>(FirstInst) || isa<CmpInst>(FirstInst)) {
|
} else if (isa<BinaryOperator>(FirstInst) || isa<CmpInst>(FirstInst)) {
|
||||||
// Can fold binop, compare or shift here if the RHS is a constant,
|
// Can fold binop, compare or shift here if the RHS is a constant,
|
||||||
// otherwise call FoldPHIArgBinOpIntoPHI.
|
// otherwise call FoldPHIArgBinOpIntoPHI.
|
||||||
ConstantOp = dyn_cast<Constant>(FirstInst->getOperand(1));
|
ConstantOp = dyn_cast<Constant>(FirstInst->getOperand(1));
|
||||||
if (ConstantOp == 0)
|
if (ConstantOp == 0)
|
||||||
return FoldPHIArgBinOpIntoPHI(PN);
|
return FoldPHIArgBinOpIntoPHI(PN);
|
||||||
|
|
||||||
if (OverflowingBinaryOperator *BO =
|
if (OverflowingBinaryOperator *BO =
|
||||||
dyn_cast<OverflowingBinaryOperator>(FirstInst)) {
|
dyn_cast<OverflowingBinaryOperator>(FirstInst)) {
|
||||||
isNUW = BO->hasNoUnsignedWrap();
|
isNUW = BO->hasNoUnsignedWrap();
|
||||||
@ -442,7 +442,7 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
|
|||||||
} else if (I->getOperand(1) != ConstantOp) {
|
} else if (I->getOperand(1) != ConstantOp) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNUW)
|
if (isNUW)
|
||||||
isNUW = cast<OverflowingBinaryOperator>(I)->hasNoUnsignedWrap();
|
isNUW = cast<OverflowingBinaryOperator>(I)->hasNoUnsignedWrap();
|
||||||
if (isNSW)
|
if (isNSW)
|
||||||
@ -486,7 +486,7 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
|
|||||||
NewCI->setDebugLoc(FirstInst->getDebugLoc());
|
NewCI->setDebugLoc(FirstInst->getDebugLoc());
|
||||||
return NewCI;
|
return NewCI;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(FirstInst)) {
|
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(FirstInst)) {
|
||||||
BinOp = BinaryOperator::Create(BinOp->getOpcode(), PhiVal, ConstantOp);
|
BinOp = BinaryOperator::Create(BinOp->getOpcode(), PhiVal, ConstantOp);
|
||||||
if (isNUW) BinOp->setHasNoUnsignedWrap();
|
if (isNUW) BinOp->setHasNoUnsignedWrap();
|
||||||
@ -495,7 +495,7 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
|
|||||||
BinOp->setDebugLoc(FirstInst->getDebugLoc());
|
BinOp->setDebugLoc(FirstInst->getDebugLoc());
|
||||||
return BinOp;
|
return BinOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
CmpInst *CIOp = cast<CmpInst>(FirstInst);
|
CmpInst *CIOp = cast<CmpInst>(FirstInst);
|
||||||
CmpInst *NewCI = CmpInst::Create(CIOp->getOpcode(), CIOp->getPredicate(),
|
CmpInst *NewCI = CmpInst::Create(CIOp->getOpcode(), CIOp->getPredicate(),
|
||||||
PhiVal, ConstantOp);
|
PhiVal, ConstantOp);
|
||||||
@ -513,7 +513,7 @@ static bool DeadPHICycle(PHINode *PN,
|
|||||||
// Remember this node, and if we find the cycle, return.
|
// Remember this node, and if we find the cycle, return.
|
||||||
if (!PotentiallyDeadPHIs.insert(PN))
|
if (!PotentiallyDeadPHIs.insert(PN))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Don't scan crazily complex things.
|
// Don't scan crazily complex things.
|
||||||
if (PotentiallyDeadPHIs.size() == 16)
|
if (PotentiallyDeadPHIs.size() == 16)
|
||||||
return false;
|
return false;
|
||||||
@ -527,16 +527,16 @@ static bool DeadPHICycle(PHINode *PN,
|
|||||||
/// PHIsEqualValue - Return true if this phi node is always equal to
|
/// PHIsEqualValue - Return true if this phi node is always equal to
|
||||||
/// NonPhiInVal. This happens with mutually cyclic phi nodes like:
|
/// NonPhiInVal. This happens with mutually cyclic phi nodes like:
|
||||||
/// z = some value; x = phi (y, z); y = phi (x, z)
|
/// z = some value; x = phi (y, z); y = phi (x, z)
|
||||||
static bool PHIsEqualValue(PHINode *PN, Value *NonPhiInVal,
|
static bool PHIsEqualValue(PHINode *PN, Value *NonPhiInVal,
|
||||||
SmallPtrSet<PHINode*, 16> &ValueEqualPHIs) {
|
SmallPtrSet<PHINode*, 16> &ValueEqualPHIs) {
|
||||||
// See if we already saw this PHI node.
|
// See if we already saw this PHI node.
|
||||||
if (!ValueEqualPHIs.insert(PN))
|
if (!ValueEqualPHIs.insert(PN))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Don't scan crazily complex things.
|
// Don't scan crazily complex things.
|
||||||
if (ValueEqualPHIs.size() == 16)
|
if (ValueEqualPHIs.size() == 16)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Scan the operands to see if they are either phi nodes or are equal to
|
// Scan the operands to see if they are either phi nodes or are equal to
|
||||||
// the value.
|
// the value.
|
||||||
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
|
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
|
||||||
@ -547,7 +547,7 @@ static bool PHIsEqualValue(PHINode *PN, Value *NonPhiInVal,
|
|||||||
} else if (Op != NonPhiInVal)
|
} else if (Op != NonPhiInVal)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -557,10 +557,10 @@ struct PHIUsageRecord {
|
|||||||
unsigned PHIId; // The ID # of the PHI (something determinstic to sort on)
|
unsigned PHIId; // The ID # of the PHI (something determinstic to sort on)
|
||||||
unsigned Shift; // The amount shifted.
|
unsigned Shift; // The amount shifted.
|
||||||
Instruction *Inst; // The trunc instruction.
|
Instruction *Inst; // The trunc instruction.
|
||||||
|
|
||||||
PHIUsageRecord(unsigned pn, unsigned Sh, Instruction *User)
|
PHIUsageRecord(unsigned pn, unsigned Sh, Instruction *User)
|
||||||
: PHIId(pn), Shift(Sh), Inst(User) {}
|
: PHIId(pn), Shift(Sh), Inst(User) {}
|
||||||
|
|
||||||
bool operator<(const PHIUsageRecord &RHS) const {
|
bool operator<(const PHIUsageRecord &RHS) const {
|
||||||
if (PHIId < RHS.PHIId) return true;
|
if (PHIId < RHS.PHIId) return true;
|
||||||
if (PHIId > RHS.PHIId) return false;
|
if (PHIId > RHS.PHIId) return false;
|
||||||
@ -570,15 +570,15 @@ struct PHIUsageRecord {
|
|||||||
RHS.Inst->getType()->getPrimitiveSizeInBits();
|
RHS.Inst->getType()->getPrimitiveSizeInBits();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LoweredPHIRecord {
|
struct LoweredPHIRecord {
|
||||||
PHINode *PN; // The PHI that was lowered.
|
PHINode *PN; // The PHI that was lowered.
|
||||||
unsigned Shift; // The amount shifted.
|
unsigned Shift; // The amount shifted.
|
||||||
unsigned Width; // The width extracted.
|
unsigned Width; // The width extracted.
|
||||||
|
|
||||||
LoweredPHIRecord(PHINode *pn, unsigned Sh, Type *Ty)
|
LoweredPHIRecord(PHINode *pn, unsigned Sh, Type *Ty)
|
||||||
: PN(pn), Shift(Sh), Width(Ty->getPrimitiveSizeInBits()) {}
|
: PN(pn), Shift(Sh), Width(Ty->getPrimitiveSizeInBits()) {}
|
||||||
|
|
||||||
// Ctor form used by DenseMap.
|
// Ctor form used by DenseMap.
|
||||||
LoweredPHIRecord(PHINode *pn, unsigned Sh)
|
LoweredPHIRecord(PHINode *pn, unsigned Sh)
|
||||||
: PN(pn), Shift(Sh), Width(0) {}
|
: PN(pn), Shift(Sh), Width(0) {}
|
||||||
@ -621,20 +621,20 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) {
|
|||||||
// PHIUsers - Keep track of all of the truncated values extracted from a set
|
// PHIUsers - Keep track of all of the truncated values extracted from a set
|
||||||
// of PHIs, along with their offset. These are the things we want to rewrite.
|
// of PHIs, along with their offset. These are the things we want to rewrite.
|
||||||
SmallVector<PHIUsageRecord, 16> PHIUsers;
|
SmallVector<PHIUsageRecord, 16> PHIUsers;
|
||||||
|
|
||||||
// PHIs are often mutually cyclic, so we keep track of a whole set of PHI
|
// PHIs are often mutually cyclic, so we keep track of a whole set of PHI
|
||||||
// nodes which are extracted from. PHIsToSlice is a set we use to avoid
|
// nodes which are extracted from. PHIsToSlice is a set we use to avoid
|
||||||
// revisiting PHIs, PHIsInspected is a ordered list of PHIs that we need to
|
// revisiting PHIs, PHIsInspected is a ordered list of PHIs that we need to
|
||||||
// check the uses of (to ensure they are all extracts).
|
// check the uses of (to ensure they are all extracts).
|
||||||
SmallVector<PHINode*, 8> PHIsToSlice;
|
SmallVector<PHINode*, 8> PHIsToSlice;
|
||||||
SmallPtrSet<PHINode*, 8> PHIsInspected;
|
SmallPtrSet<PHINode*, 8> PHIsInspected;
|
||||||
|
|
||||||
PHIsToSlice.push_back(&FirstPhi);
|
PHIsToSlice.push_back(&FirstPhi);
|
||||||
PHIsInspected.insert(&FirstPhi);
|
PHIsInspected.insert(&FirstPhi);
|
||||||
|
|
||||||
for (unsigned PHIId = 0; PHIId != PHIsToSlice.size(); ++PHIId) {
|
for (unsigned PHIId = 0; PHIId != PHIsToSlice.size(); ++PHIId) {
|
||||||
PHINode *PN = PHIsToSlice[PHIId];
|
PHINode *PN = PHIsToSlice[PHIId];
|
||||||
|
|
||||||
// Scan the input list of the PHI. If any input is an invoke, and if the
|
// Scan the input list of the PHI. If any input is an invoke, and if the
|
||||||
// input is defined in the predecessor, then we won't be split the critical
|
// input is defined in the predecessor, then we won't be split the critical
|
||||||
// edge which is required to insert a truncate. Because of this, we have to
|
// edge which is required to insert a truncate. Because of this, we have to
|
||||||
@ -644,85 +644,85 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) {
|
|||||||
if (II == 0) continue;
|
if (II == 0) continue;
|
||||||
if (II->getParent() != PN->getIncomingBlock(i))
|
if (II->getParent() != PN->getIncomingBlock(i))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// If we have a phi, and if it's directly in the predecessor, then we have
|
// If we have a phi, and if it's directly in the predecessor, then we have
|
||||||
// a critical edge where we need to put the truncate. Since we can't
|
// a critical edge where we need to put the truncate. Since we can't
|
||||||
// split the edge in instcombine, we have to bail out.
|
// split the edge in instcombine, we have to bail out.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (Value::use_iterator UI = PN->use_begin(), E = PN->use_end();
|
for (Value::use_iterator UI = PN->use_begin(), E = PN->use_end();
|
||||||
UI != E; ++UI) {
|
UI != E; ++UI) {
|
||||||
Instruction *User = cast<Instruction>(*UI);
|
Instruction *User = cast<Instruction>(*UI);
|
||||||
|
|
||||||
// If the user is a PHI, inspect its uses recursively.
|
// If the user is a PHI, inspect its uses recursively.
|
||||||
if (PHINode *UserPN = dyn_cast<PHINode>(User)) {
|
if (PHINode *UserPN = dyn_cast<PHINode>(User)) {
|
||||||
if (PHIsInspected.insert(UserPN))
|
if (PHIsInspected.insert(UserPN))
|
||||||
PHIsToSlice.push_back(UserPN);
|
PHIsToSlice.push_back(UserPN);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Truncates are always ok.
|
// Truncates are always ok.
|
||||||
if (isa<TruncInst>(User)) {
|
if (isa<TruncInst>(User)) {
|
||||||
PHIUsers.push_back(PHIUsageRecord(PHIId, 0, User));
|
PHIUsers.push_back(PHIUsageRecord(PHIId, 0, User));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise it must be a lshr which can only be used by one trunc.
|
// Otherwise it must be a lshr which can only be used by one trunc.
|
||||||
if (User->getOpcode() != Instruction::LShr ||
|
if (User->getOpcode() != Instruction::LShr ||
|
||||||
!User->hasOneUse() || !isa<TruncInst>(User->use_back()) ||
|
!User->hasOneUse() || !isa<TruncInst>(User->use_back()) ||
|
||||||
!isa<ConstantInt>(User->getOperand(1)))
|
!isa<ConstantInt>(User->getOperand(1)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unsigned Shift = cast<ConstantInt>(User->getOperand(1))->getZExtValue();
|
unsigned Shift = cast<ConstantInt>(User->getOperand(1))->getZExtValue();
|
||||||
PHIUsers.push_back(PHIUsageRecord(PHIId, Shift, User->use_back()));
|
PHIUsers.push_back(PHIUsageRecord(PHIId, Shift, User->use_back()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have no users, they must be all self uses, just nuke the PHI.
|
// If we have no users, they must be all self uses, just nuke the PHI.
|
||||||
if (PHIUsers.empty())
|
if (PHIUsers.empty())
|
||||||
return ReplaceInstUsesWith(FirstPhi, UndefValue::get(FirstPhi.getType()));
|
return ReplaceInstUsesWith(FirstPhi, UndefValue::get(FirstPhi.getType()));
|
||||||
|
|
||||||
// If this phi node is transformable, create new PHIs for all the pieces
|
// If this phi node is transformable, create new PHIs for all the pieces
|
||||||
// extracted out of it. First, sort the users by their offset and size.
|
// extracted out of it. First, sort the users by their offset and size.
|
||||||
array_pod_sort(PHIUsers.begin(), PHIUsers.end());
|
array_pod_sort(PHIUsers.begin(), PHIUsers.end());
|
||||||
|
|
||||||
DEBUG(errs() << "SLICING UP PHI: " << FirstPhi << '\n';
|
DEBUG(errs() << "SLICING UP PHI: " << FirstPhi << '\n';
|
||||||
for (unsigned i = 1, e = PHIsToSlice.size(); i != e; ++i)
|
for (unsigned i = 1, e = PHIsToSlice.size(); i != e; ++i)
|
||||||
errs() << "AND USER PHI #" << i << ": " << *PHIsToSlice[i] <<'\n';
|
errs() << "AND USER PHI #" << i << ": " << *PHIsToSlice[i] <<'\n';
|
||||||
);
|
);
|
||||||
|
|
||||||
// PredValues - This is a temporary used when rewriting PHI nodes. It is
|
// PredValues - This is a temporary used when rewriting PHI nodes. It is
|
||||||
// hoisted out here to avoid construction/destruction thrashing.
|
// hoisted out here to avoid construction/destruction thrashing.
|
||||||
DenseMap<BasicBlock*, Value*> PredValues;
|
DenseMap<BasicBlock*, Value*> PredValues;
|
||||||
|
|
||||||
// ExtractedVals - Each new PHI we introduce is saved here so we don't
|
// ExtractedVals - Each new PHI we introduce is saved here so we don't
|
||||||
// introduce redundant PHIs.
|
// introduce redundant PHIs.
|
||||||
DenseMap<LoweredPHIRecord, PHINode*> ExtractedVals;
|
DenseMap<LoweredPHIRecord, PHINode*> ExtractedVals;
|
||||||
|
|
||||||
for (unsigned UserI = 0, UserE = PHIUsers.size(); UserI != UserE; ++UserI) {
|
for (unsigned UserI = 0, UserE = PHIUsers.size(); UserI != UserE; ++UserI) {
|
||||||
unsigned PHIId = PHIUsers[UserI].PHIId;
|
unsigned PHIId = PHIUsers[UserI].PHIId;
|
||||||
PHINode *PN = PHIsToSlice[PHIId];
|
PHINode *PN = PHIsToSlice[PHIId];
|
||||||
unsigned Offset = PHIUsers[UserI].Shift;
|
unsigned Offset = PHIUsers[UserI].Shift;
|
||||||
Type *Ty = PHIUsers[UserI].Inst->getType();
|
Type *Ty = PHIUsers[UserI].Inst->getType();
|
||||||
|
|
||||||
PHINode *EltPHI;
|
PHINode *EltPHI;
|
||||||
|
|
||||||
// If we've already lowered a user like this, reuse the previously lowered
|
// If we've already lowered a user like this, reuse the previously lowered
|
||||||
// value.
|
// value.
|
||||||
if ((EltPHI = ExtractedVals[LoweredPHIRecord(PN, Offset, Ty)]) == 0) {
|
if ((EltPHI = ExtractedVals[LoweredPHIRecord(PN, Offset, Ty)]) == 0) {
|
||||||
|
|
||||||
// Otherwise, Create the new PHI node for this user.
|
// Otherwise, Create the new PHI node for this user.
|
||||||
EltPHI = PHINode::Create(Ty, PN->getNumIncomingValues(),
|
EltPHI = PHINode::Create(Ty, PN->getNumIncomingValues(),
|
||||||
PN->getName()+".off"+Twine(Offset), PN);
|
PN->getName()+".off"+Twine(Offset), PN);
|
||||||
assert(EltPHI->getType() != PN->getType() &&
|
assert(EltPHI->getType() != PN->getType() &&
|
||||||
"Truncate didn't shrink phi?");
|
"Truncate didn't shrink phi?");
|
||||||
|
|
||||||
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
|
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
|
||||||
BasicBlock *Pred = PN->getIncomingBlock(i);
|
BasicBlock *Pred = PN->getIncomingBlock(i);
|
||||||
Value *&PredVal = PredValues[Pred];
|
Value *&PredVal = PredValues[Pred];
|
||||||
|
|
||||||
// If we already have a value for this predecessor, reuse it.
|
// If we already have a value for this predecessor, reuse it.
|
||||||
if (PredVal) {
|
if (PredVal) {
|
||||||
EltPHI->addIncoming(PredVal, Pred);
|
EltPHI->addIncoming(PredVal, Pred);
|
||||||
@ -736,7 +736,7 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) {
|
|||||||
EltPHI->addIncoming(PredVal, Pred);
|
EltPHI->addIncoming(PredVal, Pred);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PHINode *InPHI = dyn_cast<PHINode>(PN)) {
|
if (PHINode *InPHI = dyn_cast<PHINode>(PN)) {
|
||||||
// If the incoming value was a PHI, and if it was one of the PHIs we
|
// If the incoming value was a PHI, and if it was one of the PHIs we
|
||||||
// already rewrote it, just use the lowered value.
|
// already rewrote it, just use the lowered value.
|
||||||
@ -746,7 +746,7 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, do an extract in the predecessor.
|
// Otherwise, do an extract in the predecessor.
|
||||||
Builder->SetInsertPoint(Pred, Pred->getTerminator());
|
Builder->SetInsertPoint(Pred, Pred->getTerminator());
|
||||||
Value *Res = InVal;
|
Value *Res = InVal;
|
||||||
@ -756,7 +756,7 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) {
|
|||||||
Res = Builder->CreateTrunc(Res, Ty, "extract.t");
|
Res = Builder->CreateTrunc(Res, Ty, "extract.t");
|
||||||
PredVal = Res;
|
PredVal = Res;
|
||||||
EltPHI->addIncoming(Res, Pred);
|
EltPHI->addIncoming(Res, Pred);
|
||||||
|
|
||||||
// If the incoming value was a PHI, and if it was one of the PHIs we are
|
// If the incoming value was a PHI, and if it was one of the PHIs we are
|
||||||
// rewriting, we will ultimately delete the code we inserted. This
|
// rewriting, we will ultimately delete the code we inserted. This
|
||||||
// means we need to revisit that PHI to make sure we extract out the
|
// means we need to revisit that PHI to make sure we extract out the
|
||||||
@ -765,22 +765,22 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) {
|
|||||||
if (PHIsInspected.count(OldInVal)) {
|
if (PHIsInspected.count(OldInVal)) {
|
||||||
unsigned RefPHIId = std::find(PHIsToSlice.begin(),PHIsToSlice.end(),
|
unsigned RefPHIId = std::find(PHIsToSlice.begin(),PHIsToSlice.end(),
|
||||||
OldInVal)-PHIsToSlice.begin();
|
OldInVal)-PHIsToSlice.begin();
|
||||||
PHIUsers.push_back(PHIUsageRecord(RefPHIId, Offset,
|
PHIUsers.push_back(PHIUsageRecord(RefPHIId, Offset,
|
||||||
cast<Instruction>(Res)));
|
cast<Instruction>(Res)));
|
||||||
++UserE;
|
++UserE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PredValues.clear();
|
PredValues.clear();
|
||||||
|
|
||||||
DEBUG(errs() << " Made element PHI for offset " << Offset << ": "
|
DEBUG(errs() << " Made element PHI for offset " << Offset << ": "
|
||||||
<< *EltPHI << '\n');
|
<< *EltPHI << '\n');
|
||||||
ExtractedVals[LoweredPHIRecord(PN, Offset, Ty)] = EltPHI;
|
ExtractedVals[LoweredPHIRecord(PN, Offset, Ty)] = EltPHI;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace the use of this piece with the PHI node.
|
// Replace the use of this piece with the PHI node.
|
||||||
ReplaceInstUsesWith(*PHIUsers[UserI].Inst, EltPHI);
|
ReplaceInstUsesWith(*PHIUsers[UserI].Inst, EltPHI);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace all the remaining uses of the PHI nodes (self uses and the lshrs)
|
// Replace all the remaining uses of the PHI nodes (self uses and the lshrs)
|
||||||
// with undefs.
|
// with undefs.
|
||||||
Value *Undef = UndefValue::get(FirstPhi.getType());
|
Value *Undef = UndefValue::get(FirstPhi.getType());
|
||||||
@ -818,7 +818,7 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) {
|
|||||||
if (DeadPHICycle(PU, PotentiallyDeadPHIs))
|
if (DeadPHICycle(PU, PotentiallyDeadPHIs))
|
||||||
return ReplaceInstUsesWith(PN, UndefValue::get(PN.getType()));
|
return ReplaceInstUsesWith(PN, UndefValue::get(PN.getType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this phi has a single use, and if that use just computes a value for
|
// If this phi has a single use, and if that use just computes a value for
|
||||||
// the next iteration of a loop, delete the phi. This occurs with unused
|
// the next iteration of a loop, delete the phi. This occurs with unused
|
||||||
// induction variables, e.g. "for (int j = 0; ; ++j);". Detecting this
|
// induction variables, e.g. "for (int j = 0; ; ++j);". Detecting this
|
||||||
@ -847,7 +847,7 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) {
|
|||||||
|
|
||||||
if (InValNo != NumIncomingVals) {
|
if (InValNo != NumIncomingVals) {
|
||||||
Value *NonPhiInVal = PN.getIncomingValue(InValNo);
|
Value *NonPhiInVal = PN.getIncomingValue(InValNo);
|
||||||
|
|
||||||
// Scan the rest of the operands to see if there are any conflicts, if so
|
// Scan the rest of the operands to see if there are any conflicts, if so
|
||||||
// there is no need to recursively scan other phis.
|
// there is no need to recursively scan other phis.
|
||||||
for (++InValNo; InValNo != NumIncomingVals; ++InValNo) {
|
for (++InValNo; InValNo != NumIncomingVals; ++InValNo) {
|
||||||
@ -855,7 +855,7 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) {
|
|||||||
if (OpVal != NonPhiInVal && !isa<PHINode>(OpVal))
|
if (OpVal != NonPhiInVal && !isa<PHINode>(OpVal))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we scanned over all operands, then we have one unique value plus
|
// If we scanned over all operands, then we have one unique value plus
|
||||||
// phi values. Scan PHI nodes to see if they all merge in each other or
|
// phi values. Scan PHI nodes to see if they all merge in each other or
|
||||||
// the value.
|
// the value.
|
||||||
@ -899,6 +899,6 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) {
|
|||||||
!TD->isLegalInteger(PN.getType()->getPrimitiveSizeInBits()))
|
!TD->isLegalInteger(PN.getType()->getPrimitiveSizeInBits()))
|
||||||
if (Instruction *Res = SliceUpIllegalIntegerPHI(PN))
|
if (Instruction *Res = SliceUpIllegalIntegerPHI(PN))
|
||||||
return Res;
|
return Res;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -838,7 +838,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
|
|||||||
Value *NewFalseOp = NegVal;
|
Value *NewFalseOp = NegVal;
|
||||||
if (AddOp != TI)
|
if (AddOp != TI)
|
||||||
std::swap(NewTrueOp, NewFalseOp);
|
std::swap(NewTrueOp, NewFalseOp);
|
||||||
Value *NewSel =
|
Value *NewSel =
|
||||||
Builder->CreateSelect(CondVal, NewTrueOp,
|
Builder->CreateSelect(CondVal, NewTrueOp,
|
||||||
NewFalseOp, SI.getName() + ".p");
|
NewFalseOp, SI.getName() + ".p");
|
||||||
|
|
||||||
@ -862,7 +862,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
|
|||||||
Value *LHS, *RHS, *LHS2, *RHS2;
|
Value *LHS, *RHS, *LHS2, *RHS2;
|
||||||
if (SelectPatternFlavor SPF = MatchSelectPattern(&SI, LHS, RHS)) {
|
if (SelectPatternFlavor SPF = MatchSelectPattern(&SI, LHS, RHS)) {
|
||||||
if (SelectPatternFlavor SPF2 = MatchSelectPattern(LHS, LHS2, RHS2))
|
if (SelectPatternFlavor SPF2 = MatchSelectPattern(LHS, LHS2, RHS2))
|
||||||
if (Instruction *R = FoldSPFofSPF(cast<Instruction>(LHS),SPF2,LHS2,RHS2,
|
if (Instruction *R = FoldSPFofSPF(cast<Instruction>(LHS),SPF2,LHS2,RHS2,
|
||||||
SI, SPF, RHS))
|
SI, SPF, RHS))
|
||||||
return R;
|
return R;
|
||||||
if (SelectPatternFlavor SPF2 = MatchSelectPattern(RHS, LHS2, RHS2))
|
if (SelectPatternFlavor SPF2 = MatchSelectPattern(RHS, LHS2, RHS2))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user