class XorOpnd {
public:
XorOpnd(Value *V);
- const XorOpnd &operator=(const XorOpnd &That);
bool isInvalid() const { return SymbolicPart == 0; }
bool isOrExpr() const { return isOr; }
}
XorOpnd::XorOpnd(Value *V) {
- assert(!isa<Constant>(V) && "No constant");
+ assert(!isa<ConstantInt>(V) && "No ConstantInt");
OrigVal = V;
Instruction *I = dyn_cast<Instruction>(V);
SymbolicRank = 0;
isOr = true;
}
-const XorOpnd &XorOpnd::operator=(const XorOpnd &That) {
- OrigVal = That.OrigVal;
- SymbolicPart = That.SymbolicPart;
- ConstPart = That.ConstPart;
- SymbolicRank = That.SymbolicRank;
- isOr = That.isOr;
- return *this;
-}
-
char Reassociate::ID = 0;
INITIALIZE_PASS(Reassociate, "reassociate",
"Reassociate expressions", false, false)
}
static bool isUnmovableInstruction(Instruction *I) {
- if (I->getOpcode() == Instruction::PHI ||
- I->getOpcode() == Instruction::LandingPad ||
- I->getOpcode() == Instruction::Alloca ||
- I->getOpcode() == Instruction::Load ||
- I->getOpcode() == Instruction::Invoke ||
- (I->getOpcode() == Instruction::Call &&
- !isa<DbgInfoIntrinsic>(I)) ||
- I->getOpcode() == Instruction::UDiv ||
- I->getOpcode() == Instruction::SDiv ||
- I->getOpcode() == Instruction::FDiv ||
- I->getOpcode() == Instruction::URem ||
- I->getOpcode() == Instruction::SRem ||
- I->getOpcode() == Instruction::FRem)
+ switch (I->getOpcode()) {
+ case Instruction::PHI:
+ case Instruction::LandingPad:
+ case Instruction::Alloca:
+ case Instruction::Load:
+ case Instruction::Invoke:
+ case Instruction::UDiv:
+ case Instruction::SDiv:
+ case Instruction::FDiv:
+ case Instruction::URem:
+ case Instruction::SRem:
+ case Instruction::FRem:
return true;
- return false;
+ case Instruction::Call:
+ return !isa<DbgInfoIntrinsic>(I);
+ default:
+ return false;
+ }
}
void Reassociate::BuildRankMap(Function &F) {
if (X != Opnd2->getSymbolicPart())
return false;
- const APInt &C1 = Opnd1->getConstPart();
- const APInt &C2 = Opnd2->getConstPart();
-
// This many instruction become dead.(At least "Opnd1 ^ Opnd2" will die.)
int DeadInstNum = 1;
if (Opnd1->getValue()->hasOneUse())
if (Opnd2->isOrExpr())
std::swap(Opnd1, Opnd2);
+ const APInt &C1 = Opnd1->getConstPart();
+ const APInt &C2 = Opnd2->getConstPart();
APInt C3((~C1) ^ C2);
// Do not increase code size!
} else if (Opnd1->isOrExpr()) {
// Xor-Rule 3: (x | c1) ^ (x | c2) = (x & c3) ^ c3 where c3 = c1 ^ c2
//
+ const APInt &C1 = Opnd1->getConstPart();
+ const APInt &C2 = Opnd2->getConstPart();
APInt C3 = C1 ^ C2;
// Do not increase code size
} else {
// Xor-Rule 4: (x & c1) ^ (x & c2) = (x & (c1^c2))
//
+ const APInt &C1 = Opnd1->getConstPart();
+ const APInt &C2 = Opnd2->getConstPart();
APInt C3 = C1 ^ C2;
Res = createAndInstr(I, X, C3);
}
XorOpnd O(V);
O.setSymbolicRank(getRank(O.getSymbolicPart()));
Opnds.push_back(O);
- OpndPtrs.push_back(&Opnds.back());
} else
ConstOpnd ^= cast<ConstantInt>(V)->getValue();
}
+ // NOTE: From this point on, do *NOT* add/delete element to/from "Opnds".
+ // It would otherwise invalidate the "Opnds"'s iterator, and hence invalidate
+ // the "OpndPtrs" as well. For the similar reason, do not fuse this loop
+ // with the previous loop --- the iterator of the "Opnds" may be invalidated
+ // when new elements are added to the vector.
+ for (unsigned i = 0, e = Opnds.size(); i != e; ++i)
+ OpndPtrs.push_back(&Opnds[i]);
+
// Step 2: Sort the Xor-Operands in a way such that the operands containing
// the same symbolic value cluster together. For instance, the input operand
// sequence ("x | 123", "y & 456", "x & 789") will be sorted into: