Add address computation stuff

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75935 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Anton Korobeynikov 2009-07-16 13:47:59 +00:00
parent dfd0dffa36
commit 711d5b68e0
3 changed files with 94 additions and 4 deletions

View File

@ -107,6 +107,9 @@ namespace {
private:
bool SelectAddrRRI(SDValue Op, SDValue Addr,
SDValue &Base, SDValue &Index, SDValue &Disp);
bool SelectLAAddr(SDValue Op, SDValue Addr,
SDValue &Base, SDValue &Index, SDValue &Disp);
SDNode *Select(SDValue Op);
bool SelectAddrRI(const SDValue& Op, SDValue& Addr,
SDValue &Base, SDValue &Disp);
@ -369,8 +372,24 @@ bool SystemZDAGToDAGISel::SelectAddrRRI(SDValue Op, SDValue Addr,
SystemZRRIAddressMode AM;
bool Done = false;
// FIXME: Should we better use lay instruction for non-single uses?
if (!Addr.hasOneUse()) {
unsigned Opcode = Addr.getOpcode();
if (Opcode != ISD::Constant && Opcode != ISD::FrameIndex) {
// If we are able to fold N into addressing mode, then we'll allow it even
// if N has multiple uses. In general, addressing computation is used as
// addresses by all of its uses. But watch out for CopyToReg uses, that
// means the address computation is liveout. It will be computed by a LA
// so we want to avoid computing the address twice.
for (SDNode::use_iterator UI = Addr.getNode()->use_begin(),
UE = Addr.getNode()->use_end(); UI != UE; ++UI) {
if (UI->getOpcode() == ISD::CopyToReg) {
MatchAddressBase(Addr, AM);
Done = true;
break;
}
}
}
}
if (!Done && MatchAddress(Addr, AM))
return false;
@ -388,11 +407,52 @@ bool SystemZDAGToDAGISel::SelectAddrRRI(SDValue Op, SDValue Addr,
else
Base = CurDAG->getTargetFrameIndex(AM.Base.FrameIndex, TLI.getPointerTy());
Index = AM.IndexReg;
Disp = Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i32);
Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i32);
return true;
}
/// SelectLAAddr - it calls SelectAddr and determines if the maximal addressing
/// mode it matches can be cost effectively emitted as an LA/LAY instruction.
bool SystemZDAGToDAGISel::SelectLAAddr(SDValue Op, SDValue Addr,
SDValue &Base, SDValue &Index, SDValue &Disp) {
SystemZRRIAddressMode AM;
if (MatchAddress(Addr, AM))
return false;
MVT VT = Addr.getValueType();
unsigned Complexity = 0;
if (AM.BaseType == SystemZRRIAddressMode::RegBase)
if (AM.Base.Reg.getNode())
Complexity = 1;
else
AM.Base.Reg = CurDAG->getRegister(0, VT);
else if (AM.BaseType == SystemZRRIAddressMode::FrameIndexBase)
Complexity = 4;
if (AM.IndexReg.getNode())
Complexity += 1;
else
AM.IndexReg = CurDAG->getRegister(0, VT);
if (AM.Disp && (AM.Base.Reg.getNode() || AM.IndexReg.getNode()))
Complexity += 1;
if (Complexity > 2) {
if (AM.BaseType == SystemZRRIAddressMode::RegBase)
Base = AM.Base.Reg;
else
Base = CurDAG->getTargetFrameIndex(AM.Base.FrameIndex,
TLI.getPointerTy());
Index = AM.IndexReg;
Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i32);
return true;
}
return false;
}
/// InstructionSelect - This callback is invoked by
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
void SystemZDAGToDAGISel::InstructionSelect() {

View File

@ -162,10 +162,16 @@ def riaddr : Operand<i64>,
// rriaddr := reg + reg + imm
def rriaddr : Operand<i64>,
ComplexPattern<i64, 3, "SelectAddrRRI", []> {
ComplexPattern<i64, 3, "SelectAddrRRI", [], []> {
let PrintMethod = "printRRIAddrOperand";
let MIOperandInfo = (ops ADDR64:$base, ADDR64:$index, i32imm:$disp);
}
def laaddr : Operand<i64>,
ComplexPattern<i64, 3, "SelectLAAddr", [add, sub, or, frameindex], []> {
let PrintMethod = "printRRIAddrOperand";
let MIOperandInfo = (ops ADDR64:$base, ADDR64:$index, i32imm:$disp);
}
//===----------------------------------------------------------------------===//
// Control Flow Instructions...
@ -176,6 +182,18 @@ let isReturn = 1, isTerminator = 1 in {
def RET : Pseudo<(outs), (ins), "br\t%r14", [(SystemZretflag)]>;
}
//===----------------------------------------------------------------------===//
// Miscellaneous Instructions.
//
let isReMaterializable = 1 in
// FIXME: Provide imm12 variant
def LA64r : Pseudo<(outs GR64:$dst), (ins laaddr:$src),
"lay\t{$dst, $src}",
[(set GR64:$dst, laaddr:$src)]>;
//===----------------------------------------------------------------------===//
// Move Instructions

View File

@ -0,0 +1,12 @@
.text
.align 4
.globl foo
.type foo,@function
foo:
.BB1_0: # entry
sllg %r1, %r3, 3
lay %r2, 8(%r1,%r2)
br %r14
.size foo, .-foo