+bool GCSE::EliminateRedundancies(Instruction *I,
+ std::vector<Value*> &EqualValues) {
+ // If the EqualValues set contains any non-instruction values, then we know
+ // that all of the instructions can be replaced with the non-instruction value
+ // because it is guaranteed to dominate all of the instructions in the
+ // function. We only have to do hard work if all we have are instructions.
+ //
+ for (unsigned i = 0, e = EqualValues.size(); i != e; ++i)
+ if (!isa<Instruction>(EqualValues[i])) {
+ // Found a non-instruction. Replace all instructions with the
+ // non-instruction.
+ //
+ Value *Replacement = EqualValues[i];
+
+ // Make sure we get I as well...
+ EqualValues[i] = I;
+
+ // Replace all instructions with the Replacement value.
+ for (i = 0; i != e; ++i)
+ if (Instruction *I = dyn_cast<Instruction>(EqualValues[i])) {
+ // Change all users of I to use Replacement.
+ I->replaceAllUsesWith(Replacement);
+
+ if (isa<LoadInst>(I))
+ ++NumLoadRemoved; // Keep track of loads eliminated
+ ++NumInstRemoved; // Keep track of number of instructions eliminated
+ ++NumNonInsts; // Keep track of number of insts repl with values
+
+ // Erase the instruction from the program.
+ I->getParent()->getInstList().erase(I);
+ }
+
+ return true;
+ }
+
+ // Remove duplicate entries from EqualValues...
+ std::sort(EqualValues.begin(), EqualValues.end());
+ EqualValues.erase(std::unique(EqualValues.begin(), EqualValues.end()),
+ EqualValues.end());
+
+ // From this point on, EqualValues is logically a vector of instructions.
+ //
+ bool Changed = false;
+ EqualValues.push_back(I); // Make sure I is included...
+ while (EqualValues.size() > 1) {
+ // FIXME, this could be done better than simple iteration!
+ Instruction *Test = cast<Instruction>(EqualValues.back());
+ EqualValues.pop_back();
+
+ for (unsigned i = 0, e = EqualValues.size(); i != e; ++i)
+ if (Instruction *Ret = EliminateCSE(Test,
+ cast<Instruction>(EqualValues[i]))) {
+ if (Ret == Test) // Eliminated EqualValues[i]
+ EqualValues[i] = Test; // Make sure that we reprocess I at some point
+ Changed = true;
+ break;
+ }
+ }
+ return Changed;
+}
+