[llvm-commits] [llvm] r48130 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/LowerSubregs.cpp lib/CodeGen/SelectionDAG/ScheduleDAG.cpp lib/Target/Target.td lib/Target/X86/X86ISelDAGToDAG.cpp lib/Target/X86/X86Instr64bit.td lib/Target/X86/X86InstrInfo.cpp lib/Target/X86/X86InstrInfo.h lib/Target/X86/X86InstrInfo.td lib/Target/X86/X86RegisterInfo.h lib/Target/X86/X86RegisterInfo.td
Christopher Lamb
christopher.lamb at gmail.com
Sun Mar 9 23:12:08 PDT 2008
Author: clamb
Date: Mon Mar 10 01:12:08 2008
New Revision: 48130
URL: http://llvm.org/viewvc/llvm-project?rev=48130&view=rev
Log:
Allow insert_subreg into implicit, target-specific values.
Change insert/extract subreg instructions to be able to be used in TableGen patterns.
Use the above features to reimplement an x86-64 pseudo instruction as a pattern.
Modified:
llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
llvm/trunk/lib/CodeGen/LowerSubregs.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
llvm/trunk/lib/Target/Target.td
llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
llvm/trunk/lib/Target/X86/X86Instr64bit.td
llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
llvm/trunk/lib/Target/X86/X86InstrInfo.h
llvm/trunk/lib/Target/X86/X86InstrInfo.td
llvm/trunk/lib/Target/X86/X86RegisterInfo.h
llvm/trunk/lib/Target/X86/X86RegisterInfo.td
Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=48130&r1=48129&r2=48130&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Mon Mar 10 01:12:08 2008
@@ -322,9 +322,12 @@
// This node takes a superreg and a constant sub-register index as operands.
EXTRACT_SUBREG,
- // INSERT_SUBREG - This node is used to insert a sub-register value.
+ // INSERT_SUBREG - This node is used to insert a sub-register value into
+ // either explicitly into a superreg, or implicitly into a superreg value.
// This node takes a superreg, a subreg value, and a constant sub-register
- // index as operands.
+ // index as operands. The superreg may be either a superregister operand or a
+ // target constant indicating that the insert is being done into a target
+ // specific implicit value.
INSERT_SUBREG,
// MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing
Modified: llvm/trunk/lib/CodeGen/LowerSubregs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LowerSubregs.cpp?rev=48130&r1=48129&r2=48130&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LowerSubregs.cpp (original)
+++ llvm/trunk/lib/CodeGen/LowerSubregs.cpp Mon Mar 10 01:12:08 2008
@@ -105,32 +105,21 @@
MachineFunction &MF = *MBB->getParent();
const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo();
const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
- unsigned DstReg = 0;
+ assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) &&
+ ((MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) ||
+ MI->getOperand(1).isImmediate()) &&
+ (MI->getOperand(2).isRegister() && MI->getOperand(2).isUse()) &&
+ MI->getOperand(3).isImmediate() && "Invalid insert_subreg");
+
+ unsigned DstReg = MI->getOperand(0).getReg();
unsigned SrcReg = 0;
- unsigned InsReg = 0;
- unsigned SubIdx = 0;
-
- // If only have 3 operands, then the source superreg is undef
- // and we can supress the copy from the undef value
- if (MI->getNumOperands() == 3) {
- assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) &&
- (MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) &&
- MI->getOperand(2).isImmediate() && "Invalid extract_subreg");
- DstReg = MI->getOperand(0).getReg();
+ // Check if we're inserting into an implicit value.
+ if (MI->getOperand(1).isImmediate())
SrcReg = DstReg;
- InsReg = MI->getOperand(1).getReg();
- SubIdx = MI->getOperand(2).getImm();
- } else if (MI->getNumOperands() == 4) {
- assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) &&
- (MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) &&
- (MI->getOperand(2).isRegister() && MI->getOperand(2).isUse()) &&
- MI->getOperand(3).isImmediate() && "Invalid extract_subreg");
- DstReg = MI->getOperand(0).getReg();
+ else
SrcReg = MI->getOperand(1).getReg();
- InsReg = MI->getOperand(2).getReg();
- SubIdx = MI->getOperand(3).getImm();
- } else
- assert(0 && "Malformed extract_subreg");
+ unsigned InsReg = MI->getOperand(2).getReg();
+ unsigned SubIdx = MI->getOperand(3).getImm();
assert(SubIdx != 0 && "Invalid index for extract_subreg");
unsigned DstSubReg = TRI.getSubReg(DstReg, SubIdx);
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=48130&r1=48129&r2=48130&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Mon Mar 10 01:12:08 2008
@@ -693,19 +693,13 @@
MI->addOperand(MachineOperand::CreateImm(SubIdx));
} else if (Opc == TargetInstrInfo::INSERT_SUBREG) {
- assert((Node->getNumOperands() == 2 || Node->getNumOperands() == 3) &&
+ assert((Node->getNumOperands() == 3) &&
"Malformed insert_subreg node");
- bool isUndefInput = (Node->getNumOperands() == 2);
- unsigned SubReg = 0;
- unsigned SubIdx = 0;
-
- if (isUndefInput) {
- SubReg = getVR(Node->getOperand(0), VRBaseMap);
- SubIdx = cast<ConstantSDNode>(Node->getOperand(1))->getValue();
- } else {
- SubReg = getVR(Node->getOperand(1), VRBaseMap);
- SubIdx = cast<ConstantSDNode>(Node->getOperand(2))->getValue();
- }
+ SDOperand N0 = Node->getOperand(0);
+ SDOperand N1 = Node->getOperand(1);
+ SDOperand N2 = Node->getOperand(2);
+ unsigned SubReg = getVR(N1, VRBaseMap);
+ unsigned SubIdx = cast<ConstantSDNode>(N2)->getValue();
// TODO: Add tracking info to MachineRegisterInfo of which vregs are subregs
// to allow coalescing in the allocator
@@ -743,9 +737,15 @@
}
MI->addOperand(MachineOperand::CreateReg(VRBase, true));
- AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap);
- if (!isUndefInput)
- AddOperand(MI, Node->getOperand(1), 0, 0, VRBaseMap);
+
+ // If N0 is a constant then it indicates the insert is being done
+ // into a target specific constant value, not a register.
+ if (const ConstantSDNode *SD = dyn_cast<ConstantSDNode>(N0))
+ MI->addOperand(MachineOperand::CreateImm(SD->getValue()));
+ else
+ AddOperand(MI, N0, 0, 0, VRBaseMap);
+ // Add the subregster being inserted
+ AddOperand(MI, N1, 0, 0, VRBaseMap);
MI->addOperand(MachineOperand::CreateImm(SubIdx));
} else
assert(0 && "Node is not a subreg insert or extract");
Modified: llvm/trunk/lib/Target/Target.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Target.td?rev=48130&r1=48129&r2=48130&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Target.td (original)
+++ llvm/trunk/lib/Target/Target.td Mon Mar 10 01:12:08 2008
@@ -263,6 +263,10 @@
/// flags. But currently we have but one flag.
def ptr_rc;
+/// unknown definition - Mark this operand as being of unknown type, causing
+/// it to be resolved by inference in the context it is used.
+def unknown;
+
/// Operand Types - These provide the built-in operand types that may be used
/// by a target. Targets can optionally provide their own operand types as
/// needed, though this should not be needed for RISC targets.
@@ -351,15 +355,15 @@
let hasCtrlDep = 1;
}
def EXTRACT_SUBREG : Instruction {
- let OutOperandList = (ops variable_ops);
- let InOperandList = (ops variable_ops);
+ let OutOperandList = (ops unknown:$dst);
+ let InOperandList = (ops unknown:$supersrc, i32imm:$subidx);
let AsmString = "";
let Namespace = "TargetInstrInfo";
let neverHasSideEffects = 1;
}
def INSERT_SUBREG : Instruction {
- let OutOperandList = (ops variable_ops);
- let InOperandList = (ops variable_ops);
+ let OutOperandList = (ops unknown:$dst);
+ let InOperandList = (ops unknown:$supersrc, unknown:$subsrc, i32imm:$subidx);
let AsmString = "";
let Namespace = "TargetInstrInfo";
let neverHasSideEffects = 1;
Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=48130&r1=48129&r2=48130&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Mon Mar 10 01:12:08 2008
@@ -1491,22 +1491,27 @@
AddToISelQueue(N0);
if (NVT == MVT::i64 || NVT == MVT::i32 || NVT == MVT::i16) {
SDOperand SRIdx;
+ SDOperand ImplVal = CurDAG->getTargetConstant(X86::IMPL_VAL_UNDEF,
+ MVT::i32);
switch(N0.getValueType()) {
case MVT::i32:
- SRIdx = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3
+ SRIdx = CurDAG->getTargetConstant(X86::SUBREG_32BIT, MVT::i32);
+ // x86-64 zero extends 32-bit inserts int 64-bit registers
+ if (Subtarget->is64Bit())
+ ImplVal = CurDAG->getTargetConstant(X86::IMPL_VAL_ZERO, MVT::i32);
break;
case MVT::i16:
- SRIdx = CurDAG->getTargetConstant(2, MVT::i32); // SubRegSet 2
+ SRIdx = CurDAG->getTargetConstant(X86::SUBREG_16BIT, MVT::i32);
break;
case MVT::i8:
if (Subtarget->is64Bit())
- SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1
+ SRIdx = CurDAG->getTargetConstant(X86::SUBREG_8BIT, MVT::i32);
break;
default: assert(0 && "Unknown any_extend!");
}
if (SRIdx.Val) {
SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG,
- NVT, N0, SRIdx);
+ NVT, ImplVal, N0, SRIdx);
#ifndef NDEBUG
DOUT << std::string(Indent-2, ' ') << "=> ";
Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=48130&r1=48129&r2=48130&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original)
+++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Mon Mar 10 01:12:08 2008
@@ -1098,12 +1098,11 @@
"mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
[(set GR64:$dst, (zextloadi64i32 addr:$src))]>;
-/// PsAND64rrFFFFFFFF - r = r & (2^32-1)
-def PsAND64rrFFFFFFFF
- : I<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
- "mov{l}\t{${src:subreg32}, ${dst:subreg32}|${dst:subreg32}, ${src:subreg32}}",
- [(set GR64:$dst, (and GR64:$src, i64immFFFFFFFF))]>;
-
+// r & (2^32-1)
+def : Pat<(and GR64:$src, i64immFFFFFFFF),
+ (INSERT_SUBREG x86_impl_val_zero,
+ (MOV32rr (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)),
+ x86_subreg_32bit)>;
// Alias instructions that map movr0 to xor. Use xorl instead of xorq; it's
// equivalent due to implicit zero-extending, and it sometimes has a smaller
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=48130&r1=48129&r2=48130&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Mon Mar 10 01:12:08 2008
@@ -903,16 +903,20 @@
? X86::LEA64_32r : X86::LEA32r;
unsigned leaInReg = RegInfo.createVirtualRegister(&X86::GR32RegClass);
unsigned leaOutReg = RegInfo.createVirtualRegister(&X86::GR32RegClass);
-
- MachineInstr *Ins =
- BuildMI(get(X86::INSERT_SUBREG), leaInReg).addReg(Src).addImm(2);
+
+ // Build and insert into an implicit UNDEF value. This is OK because
+ // well be shifting and then extracting the lower 16-bits.
+ MachineInstr *Ins =
+ BuildMI(get(X86::INSERT_SUBREG),leaInReg).addImm(X86::IMPL_VAL_UNDEF)
+ .addReg(Src).addImm(X86::SUBREG_16BIT);
Ins->copyKillDeadInfo(MI);
NewMI = BuildMI(get(Opc), leaOutReg)
.addReg(0).addImm(1 << ShAmt).addReg(leaInReg).addImm(0);
MachineInstr *Ext =
- BuildMI(get(X86::EXTRACT_SUBREG), Dest).addReg(leaOutReg).addImm(2);
+ BuildMI(get(X86::EXTRACT_SUBREG), Dest)
+ .addReg(leaOutReg).addImm(X86::SUBREG_16BIT);
Ext->copyKillDeadInfo(MI);
MFI->insert(MBBI, Ins); // Insert the insert_subreg
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.h?rev=48130&r1=48129&r2=48130&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.h (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.h Mon Mar 10 01:12:08 2008
@@ -46,6 +46,14 @@
COND_INVALID
};
+ // X86 specific implict values used for subregister inserts.
+ // This can be used to model the fact that x86-64 by default
+ // inserts 32-bit values into 64-bit registers implicitly containing zeros.
+ enum ImplicitVal {
+ IMPL_VAL_UNDEF = 0,
+ IMPL_VAL_ZERO = 1
+ };
+
// Turn condition code into conditional branch opcode.
unsigned GetCondBranchFromCond(CondCode CC);
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=48130&r1=48129&r2=48130&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Mon Mar 10 01:12:08 2008
@@ -161,6 +161,10 @@
// Branch targets have OtherVT type.
def brtarget : Operand<OtherVT>;
+// These should match the enum X86::ImplicitVal
+def x86_impl_val_undef : PatLeaf<(i32 0)>;
+def x86_impl_val_zero : PatLeaf<(i32 1)>;
+
//===----------------------------------------------------------------------===//
// X86 Complex Pattern Definitions.
//
Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.h?rev=48130&r1=48129&r2=48130&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86RegisterInfo.h (original)
+++ llvm/trunk/lib/Target/X86/X86RegisterInfo.h Mon Mar 10 01:12:08 2008
@@ -32,6 +32,15 @@
};
}
+namespace X86 {
+ /// SubregIndex - The index of various sized subregister classes. Note that
+ /// these indices must be kept in sync with the class indices in the
+ /// X86RegisterInfo.td file.
+ enum SubregIndex {
+ SUBREG_8BIT = 1, SUBREG_16BIT = 2, SUBREG_32BIT = 3
+ };
+}
+
/// DWARFFlavour - Flavour of dwarf regnumbers
///
namespace DWARFFlavour {
Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.td?rev=48130&r1=48129&r2=48130&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86RegisterInfo.td (original)
+++ llvm/trunk/lib/Target/X86/X86RegisterInfo.td Mon Mar 10 01:12:08 2008
@@ -176,6 +176,10 @@
// sub registers for each register.
//
+def x86_subreg_8bit : PatLeaf<(i32 1)>;
+def x86_subreg_16bit : PatLeaf<(i32 2)>;
+def x86_subreg_32bit : PatLeaf<(i32 3)>;
+
def : SubRegSet<1, [AX, CX, DX, BX, SP, BP, SI, DI,
R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W],
[AL, CL, DL, BL, SPL, BPL, SIL, DIL,
More information about the llvm-commits
mailing list