[llvm-commits] [llvm] r85515 - /llvm/trunk/lib/CodeGen/MachineLICM.cpp
Dan Gohman
gohman at apple.com
Thu Oct 29 10:47:20 PDT 2009
Author: djg
Date: Thu Oct 29 12:47:20 2009
New Revision: 85515
URL: http://llvm.org/viewvc/llvm-project?rev=85515&view=rev
Log:
Refactor the code for unfolding a load into a separate function.
Modified:
llvm/trunk/lib/CodeGen/MachineLICM.cpp
Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=85515&r1=85514&r2=85515&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Thu Oct 29 12:47:20 2009
@@ -105,6 +105,12 @@
///
void HoistRegion(MachineDomTreeNode *N);
+ /// ExtractHoistableLoad - Unfold a load from the given machineinstr if
+ /// the load itself could be hoisted. Return the unfolded and hoistable
+ /// load, or null if the load couldn't be unfolded or if it wouldn't
+ /// be hoistable.
+ MachineInstr *ExtractHoistableLoad(MachineInstr *MI);
+
/// Hoist - When an instruction is found to only use loop invariant operands
/// that is safe to hoist, this instruction is called to do the dirty work.
///
@@ -369,62 +375,68 @@
return 0;
}
+MachineInstr *MachineLICM::ExtractHoistableLoad(MachineInstr *MI) {
+ // If not, we may be able to unfold a load and hoist that.
+ // First test whether the instruction is loading from an amenable
+ // memory location.
+ if (!MI->getDesc().mayLoad()) return 0;
+ if (!MI->hasOneMemOperand()) return 0;
+ MachineMemOperand *MMO = *MI->memoperands_begin();
+ if (MMO->isVolatile()) return 0;
+ MachineFunction &MF = *MI->getParent()->getParent();
+ if (!MMO->getValue()) return 0;
+ if (const PseudoSourceValue *PSV =
+ dyn_cast<PseudoSourceValue>(MMO->getValue())) {
+ if (!PSV->isConstant(MF.getFrameInfo())) return 0;
+ } else {
+ if (!AA->pointsToConstantMemory(MMO->getValue())) return 0;
+ }
+ // Next determine the register class for a temporary register.
+ unsigned NewOpc =
+ TII->getOpcodeAfterMemoryUnfold(MI->getOpcode(),
+ /*UnfoldLoad=*/true,
+ /*UnfoldStore=*/false);
+ if (NewOpc == 0) return 0;
+ const TargetInstrDesc &TID = TII->get(NewOpc);
+ if (TID.getNumDefs() != 1) return 0;
+ const TargetRegisterClass *RC = TID.OpInfo[0].getRegClass(TRI);
+ // Ok, we're unfolding. Create a temporary register and do the unfold.
+ unsigned Reg = RegInfo->createVirtualRegister(RC);
+ SmallVector<MachineInstr *, 2> NewMIs;
+ bool Success =
+ TII->unfoldMemoryOperand(MF, MI, Reg,
+ /*UnfoldLoad=*/true, /*UnfoldStore=*/false,
+ NewMIs);
+ (void)Success;
+ assert(Success &&
+ "unfoldMemoryOperand failed when getOpcodeAfterMemoryUnfold "
+ "succeeded!");
+ assert(NewMIs.size() == 2 &&
+ "Unfolded a load into multiple instructions!");
+ MachineBasicBlock *MBB = MI->getParent();
+ MBB->insert(MI, NewMIs[0]);
+ MBB->insert(MI, NewMIs[1]);
+ // If unfolding produced a load that wasn't loop-invariant or profitable to
+ // hoist, discard the new instructions and bail.
+ if (!IsLoopInvariantInst(*NewMIs[0]) || !IsProfitableToHoist(*NewMIs[0])) {
+ NewMIs[0]->eraseFromParent();
+ NewMIs[1]->eraseFromParent();
+ return 0;
+ }
+ // Otherwise we successfully unfolded a load that we can hoist.
+ MI->eraseFromParent();
+ return NewMIs[0];
+}
+
/// Hoist - When an instruction is found to use only loop invariant operands
/// that are safe to hoist, this instruction is called to do the dirty work.
///
void MachineLICM::Hoist(MachineInstr *MI) {
// First check whether we should hoist this instruction.
if (!IsLoopInvariantInst(*MI) || !IsProfitableToHoist(*MI)) {
- // If not, we may be able to unfold a load and hoist that.
- // First test whether the instruction is loading from an amenable
- // memory location.
- if (!MI->getDesc().mayLoad()) return;
- if (!MI->hasOneMemOperand()) return;
- MachineMemOperand *MMO = *MI->memoperands_begin();
- if (MMO->isVolatile()) return;
- MachineFunction &MF = *MI->getParent()->getParent();
- if (!MMO->getValue()) return;
- if (const PseudoSourceValue *PSV =
- dyn_cast<PseudoSourceValue>(MMO->getValue())) {
- if (!PSV->isConstant(MF.getFrameInfo())) return;
- } else {
- if (!AA->pointsToConstantMemory(MMO->getValue())) return;
- }
- // Next determine the register class for a temporary register.
- unsigned NewOpc =
- TII->getOpcodeAfterMemoryUnfold(MI->getOpcode(),
- /*UnfoldLoad=*/true,
- /*UnfoldStore=*/false);
- if (NewOpc == 0) return;
- const TargetInstrDesc &TID = TII->get(NewOpc);
- if (TID.getNumDefs() != 1) return;
- const TargetRegisterClass *RC = TID.OpInfo[0].getRegClass(TRI);
- // Ok, we're unfolding. Create a temporary register and do the unfold.
- unsigned Reg = RegInfo->createVirtualRegister(RC);
- SmallVector<MachineInstr *, 2> NewMIs;
- bool Success =
- TII->unfoldMemoryOperand(MF, MI, Reg,
- /*UnfoldLoad=*/true, /*UnfoldStore=*/false,
- NewMIs);
- (void)Success;
- assert(Success &&
- "unfoldMemoryOperand failed when getOpcodeAfterMemoryUnfold "
- "succeeded!");
- assert(NewMIs.size() == 2 &&
- "Unfolded a load into multiple instructions!");
- MachineBasicBlock *MBB = MI->getParent();
- MBB->insert(MI, NewMIs[0]);
- MBB->insert(MI, NewMIs[1]);
- // If unfolding produced a load that wasn't loop-invariant or profitable to
- // hoist, discard the new instructions and bail.
- if (!IsLoopInvariantInst(*NewMIs[0]) || !IsProfitableToHoist(*NewMIs[0])) {
- NewMIs[0]->eraseFromParent();
- NewMIs[1]->eraseFromParent();
- return;
- }
- // Otherwise we successfully unfolded a load that we can hoist.
- MI->eraseFromParent();
- MI = NewMIs[0];
+ // If not, try unfolding a hoistable load.
+ MI = ExtractHoistableLoad(MI);
+ if (!MI) return;
}
// Now move the instructions to the predecessor, inserting it before any
More information about the llvm-commits
mailing list