+ const TargetInstrDesc &TID = I.getDesc();
+
+ // Ignore stuff that we obviously can't hoist.
+ if (TID.mayStore() || TID.isCall() || TID.isReturn() || TID.isBranch() ||
+ TID.hasUnmodeledSideEffects())
+ return false;
+
+ if (TID.mayLoad()) {
+ // Okay, this instruction does a load. As a refinement, allow the target
+ // to decide whether the loaded value is actually a constant. If so, we
+ // can actually use it as a load.
+ if (!TII->isInvariantLoad(&I)) {
+ // FIXME: we should be able to sink loads with no other side effects if
+ // there is nothing that can change memory from here until the end of
+ // block. This is a trivial form of alias analysis.
+ return false;
+ }
+ }
+
+ DEBUG({
+ DOUT << "--- Checking if we can hoist " << I;
+ if (I.getDesc().getImplicitUses()) {
+ DOUT << " * Instruction has implicit uses:\n";
+
+ const TargetRegisterInfo *TRI = TM->getRegisterInfo();
+ for (const unsigned *ImpUses = I.getDesc().getImplicitUses();
+ *ImpUses; ++ImpUses)
+ DOUT << " -> " << TRI->getName(*ImpUses) << "\n";
+ }
+
+ if (I.getDesc().getImplicitDefs()) {
+ DOUT << " * Instruction has implicit defines:\n";
+
+ const TargetRegisterInfo *TRI = TM->getRegisterInfo();
+ for (const unsigned *ImpDefs = I.getDesc().getImplicitDefs();
+ *ImpDefs; ++ImpDefs)
+ DOUT << " -> " << TRI->getName(*ImpDefs) << "\n";
+ }
+
+ //if (TII->hasUnmodelledSideEffects(&I))
+ //DOUT << " * Instruction has side effects.\n";
+ });