Change unfoldMemoryOperand(). User is now responsible for passing in the

register used by the unfolded instructions. User can also specify whether to
unfold the load, the store, or both.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42946 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2007-10-13 02:35:06 +00:00
parent fa9457276a
commit 106e8020bd
3 changed files with 20 additions and 13 deletions

View File

@ -567,7 +567,7 @@ public:
/// a a store or a load and a store into two or more instruction. If this is /// a a store or a load and a store into two or more instruction. If this is
/// possible, returns true as well as the new instructions by reference. /// possible, returns true as well as the new instructions by reference.
virtual bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, virtual bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI,
SSARegMap *RegMap, unsigned Reg, bool UnfoldLoad, bool UnfoldStore,
SmallVector<MachineInstr*, 4> &NewMIs) const{ SmallVector<MachineInstr*, 4> &NewMIs) const{
return false; return false;
} }

View File

@ -1118,7 +1118,7 @@ MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr *MI, unsigned OpNu
} }
bool X86RegisterInfo::unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, bool X86RegisterInfo::unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI,
SSARegMap *RegMap, unsigned Reg, bool UnfoldLoad, bool UnfoldStore,
SmallVector<MachineInstr*, 4> &NewMIs) const { SmallVector<MachineInstr*, 4> &NewMIs) const {
DenseMap<unsigned*, std::pair<unsigned,unsigned> >::iterator I = DenseMap<unsigned*, std::pair<unsigned,unsigned> >::iterator I =
MemOp2RegOpTable.find((unsigned*)MI->getOpcode()); MemOp2RegOpTable.find((unsigned*)MI->getOpcode());
@ -1128,6 +1128,13 @@ bool X86RegisterInfo::unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI,
unsigned Index = I->second.second & 0xf; unsigned Index = I->second.second & 0xf;
bool HasLoad = I->second.second & (1 << 4); bool HasLoad = I->second.second & (1 << 4);
bool HasStore = I->second.second & (1 << 5); bool HasStore = I->second.second & (1 << 5);
if (UnfoldLoad && !HasLoad)
return false;
HasLoad &= UnfoldLoad;
if (UnfoldStore && !HasStore)
return false;
HasStore &= UnfoldStore;
const TargetInstrDescriptor &TID = TII.get(Opc); const TargetInstrDescriptor &TID = TII.get(Opc);
const TargetOperandInfo &TOI = TID.OpInfo[Index]; const TargetOperandInfo &TOI = TID.OpInfo[Index];
const TargetRegisterClass *RC = (TOI.Flags & M_LOOK_UP_PTR_REG_CLASS) const TargetRegisterClass *RC = (TOI.Flags & M_LOOK_UP_PTR_REG_CLASS)
@ -1149,10 +1156,8 @@ bool X86RegisterInfo::unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI,
} }
// Emit the load instruction. // Emit the load instruction.
unsigned LoadReg = 0;
if (HasLoad) { if (HasLoad) {
LoadReg = RegMap->createVirtualRegister(RC); loadRegFromAddr(MF, Reg, AddrOps, RC, NewMIs);
loadRegFromAddr(MF, LoadReg, AddrOps, RC, NewMIs);
if (HasStore) { if (HasStore) {
// Address operands cannot be marked isKill. // Address operands cannot be marked isKill.
for (unsigned i = 1; i != 5; ++i) { for (unsigned i = 1; i != 5; ++i) {
@ -1164,27 +1169,29 @@ bool X86RegisterInfo::unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI,
} }
// Emit the data processing instruction. // Emit the data processing instruction.
MachineInstrBuilder MIB = BuildMI(TII.get(Opc)); MachineInstr *DataMI = new MachineInstr (TID, true);
unsigned StoreReg = 0; MachineInstrBuilder MIB(DataMI);
const TargetRegisterClass *DstRC = 0; const TargetRegisterClass *DstRC = 0;
if (HasStore) { if (HasStore) {
const TargetOperandInfo &DstTOI = TID.OpInfo[0]; const TargetOperandInfo &DstTOI = TID.OpInfo[0];
DstRC = (DstTOI.Flags & M_LOOK_UP_PTR_REG_CLASS) DstRC = (DstTOI.Flags & M_LOOK_UP_PTR_REG_CLASS)
? TII.getPointerRegClass() : getRegClass(DstTOI.RegClass); ? TII.getPointerRegClass() : getRegClass(DstTOI.RegClass);
StoreReg = RegMap->createVirtualRegister(RC); MIB.addReg(Reg, true);
MIB.addReg(StoreReg, true);
} }
for (unsigned i = 0, e = BeforeOps.size(); i != e; ++i) for (unsigned i = 0, e = BeforeOps.size(); i != e; ++i)
MIB = X86InstrAddOperand(MIB, BeforeOps[i]); MIB = X86InstrAddOperand(MIB, BeforeOps[i]);
if (LoadReg) MIB.addReg(Reg);
MIB.addReg(LoadReg);
for (unsigned i = 0, e = AfterOps.size(); i != e; ++i) for (unsigned i = 0, e = AfterOps.size(); i != e; ++i)
MIB = X86InstrAddOperand(MIB, AfterOps[i]); MIB = X86InstrAddOperand(MIB, AfterOps[i]);
for (unsigned i = 0, e = ImpOps.size(); i != e; ++i) {
MachineOperand &MO = ImpOps[i];
MIB.addReg(MO.getReg(), MO.isDef(), true, MO.isKill(), MO.isDead());
}
NewMIs.push_back(MIB); NewMIs.push_back(MIB);
// Emit the store instruction. // Emit the store instruction.
if (HasStore) if (HasStore)
storeRegToAddr(MF, StoreReg, AddrOps, DstRC, NewMIs); storeRegToAddr(MF, Reg, AddrOps, DstRC, NewMIs);
return true; return true;
} }

View File

@ -136,7 +136,7 @@ public:
/// a store or a load and a store into two or more instruction. If this is /// a store or a load and a store into two or more instruction. If this is
/// possible, returns true as well as the new instructions by reference. /// possible, returns true as well as the new instructions by reference.
bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI,
SSARegMap *RegMap, unsigned Reg, bool UnfoldLoad, bool UnfoldStore,
SmallVector<MachineInstr*, 4> &NewMIs) const; SmallVector<MachineInstr*, 4> &NewMIs) const;
bool unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N, bool unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N,