[LLVMdev] distinguishing between real arguments and variable arguments
reed kotler
rkotler at mips.com
Mon Sep 26 13:40:36 PDT 2011
I'm doing the delay slot optimization for MIPS and I've noticed that two
other ports that are doing this have to work around a problem in the
instruction abstraction.
Would be nice to fix this and not propagate the hack.
The basic problem is that on a call, you want to get the set of explicit
and implicit operands but NOT the variable operands.
There is no way do this without hardcoding this information away from
the TD file which is error prone.
Architectures evolve and you can get new call instructions and then have
a subtle delay slot bug.
Any suggestions on how to fix LLVM so that we can get the non variable
operands?
In Mblaze:
static unsigned getLastRealOperand(MachineBasicBlock::iterator &instr) {
switch (instr->getOpcode()) {
default: return instr->getNumOperands();
// These instructions have a variable number of operands but the
first two
// are the "real" operands that we care about during hazard detection.
case MBlaze::BRLID:
case MBlaze::BRALID:
case MBlaze::BRLD:
case MBlaze::BRALD:
return 2;
}
}
In Sparc:
void Filler::insertCallUses(MachineBasicBlock::iterator MI,
SmallSet<unsigned, 32>& RegUses)
{
switch(MI->getOpcode()) {
default: llvm_unreachable("Unknown opcode.");
case SP::CALL: break;
case SP::JMPLrr:
case SP::JMPLri:
assert(MI->getNumOperands() >= 2);
const MachineOperand &Reg = MI->getOperand(0);
assert(Reg.isReg() && "JMPL first operand is not a register.");
assert(Reg.isUse() && "JMPL first operand is not a use.");
RegUses.insert(Reg.getReg());
const MachineOperand &RegOrImm = MI->getOperand(1);
if (RegOrImm.isImm())
break;
assert(RegOrImm.isReg() && "JMPLrr second operand is not a register.");
assert(RegOrImm.isUse() && "JMPLrr second operand is not a use.");
RegUses.insert(RegOrImm.getReg());
break;
}
}
More information about the llvm-dev
mailing list