[llvm] r198614 - XCore target: Lower FRAME_TO_ARGS_OFFSET
Robert Lytton
robert at xmos.com
Mon Jan 6 06:21:00 PST 2014
Author: rlytton
Date: Mon Jan 6 08:21:00 2014
New Revision: 198614
URL: http://llvm.org/viewvc/llvm-project?rev=198614&view=rev
Log:
XCore target: Lower FRAME_TO_ARGS_OFFSET
This requires a knowledge of the stack size which is not known until
the frame is complete, hence the need for the XCoreFTAOElim pass
which lowers the XCoreISD::FRAME_TO_ARGS_OFFSET instrution into its
final form.
Added:
llvm/trunk/lib/Target/XCore/XCoreFrameToArgsOffsetElim.cpp
Modified:
llvm/trunk/lib/Target/XCore/CMakeLists.txt
llvm/trunk/lib/Target/XCore/XCore.h
llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp
llvm/trunk/lib/Target/XCore/XCoreISelLowering.h
llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td
llvm/trunk/lib/Target/XCore/XCoreTargetMachine.cpp
llvm/trunk/test/CodeGen/XCore/llvm-intrinsics.ll
Modified: llvm/trunk/lib/Target/XCore/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/CMakeLists.txt?rev=198614&r1=198613&r2=198614&view=diff
==============================================================================
--- llvm/trunk/lib/Target/XCore/CMakeLists.txt (original)
+++ llvm/trunk/lib/Target/XCore/CMakeLists.txt Mon Jan 6 08:21:00 2014
@@ -24,6 +24,7 @@ add_llvm_target(XCoreCodeGen
XCoreTargetObjectFile.cpp
XCoreTargetTransformInfo.cpp
XCoreSelectionDAGInfo.cpp
+ XCoreFrameToArgsOffsetElim.cpp
)
add_subdirectory(Disassembler)
Modified: llvm/trunk/lib/Target/XCore/XCore.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCore.h?rev=198614&r1=198613&r2=198614&view=diff
==============================================================================
--- llvm/trunk/lib/Target/XCore/XCore.h (original)
+++ llvm/trunk/lib/Target/XCore/XCore.h Mon Jan 6 08:21:00 2014
@@ -27,6 +27,7 @@ namespace llvm {
void initializeXCoreLowerThreadLocalPass(PassRegistry &p);
+ FunctionPass *createXCoreFrameToArgsOffsetEliminationPass();
FunctionPass *createXCoreISelDag(XCoreTargetMachine &TM,
CodeGenOpt::Level OptLevel);
ModulePass *createXCoreLowerThreadLocalPass();
Added: llvm/trunk/lib/Target/XCore/XCoreFrameToArgsOffsetElim.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreFrameToArgsOffsetElim.cpp?rev=198614&view=auto
==============================================================================
--- llvm/trunk/lib/Target/XCore/XCoreFrameToArgsOffsetElim.cpp (added)
+++ llvm/trunk/lib/Target/XCore/XCoreFrameToArgsOffsetElim.cpp Mon Jan 6 08:21:00 2014
@@ -0,0 +1,70 @@
+//===-- XCoreFrameToArgsOffsetElim.cpp ----------------------------*- C++ -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Replace Pseudo FRAME_TO_ARGS_OFFSET with the appropriate real offset.
+//
+//===----------------------------------------------------------------------===//
+
+#include "XCore.h"
+#include "XCoreInstrInfo.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetMachine.h"
+using namespace llvm;
+
+namespace {
+ struct XCoreFTAOElim : public MachineFunctionPass {
+ static char ID;
+ XCoreFTAOElim() : MachineFunctionPass(ID) {}
+
+ virtual bool runOnMachineFunction(MachineFunction &Fn);
+
+ virtual const char *getPassName() const {
+ return "XCore FRAME_TO_ARGS_OFFSET Elimination";
+ }
+ };
+ char XCoreFTAOElim::ID = 0;
+}
+
+/// createXCoreFrameToArgsOffsetEliminationPass - returns an instance of the
+/// Frame to args offset elimination pass
+FunctionPass *llvm::createXCoreFrameToArgsOffsetEliminationPass() {
+ return new XCoreFTAOElim();
+}
+
+static inline bool isImmU6(unsigned val) {
+ return val < (1 << 6);
+}
+
+static inline bool isImmU16(unsigned val) {
+ return val < (1 << 16);
+}
+
+bool XCoreFTAOElim::runOnMachineFunction(MachineFunction &MF) {
+ const XCoreInstrInfo &TII =
+ *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo());
+ unsigned StackSize = MF.getFrameInfo()->getStackSize();
+ for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E;
+ ++MFI) {
+ MachineBasicBlock &MBB = *MFI;
+ for (MachineBasicBlock::iterator MBBI = MBB.begin(), EE = MBB.end();
+ MBBI != EE; ++MBBI) {
+ if (MBBI->getOpcode() == XCore::FRAME_TO_ARGS_OFFSET) {
+ MachineInstr *OldInst = MBBI;
+ unsigned Reg = OldInst->getOperand(0).getReg();
+ MBBI = TII.loadImmediate(MBB, MBBI, Reg, StackSize);
+ OldInst->eraseFromParent();
+ }
+ }
+ }
+ return true;
+}
Modified: llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp?rev=198614&r1=198613&r2=198614&view=diff
==============================================================================
--- llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp Mon Jan 6 08:21:00 2014
@@ -60,6 +60,7 @@ getTargetNodeName(unsigned Opcode) const
case XCoreISD::CRC8 : return "XCoreISD::CRC8";
case XCoreISD::BR_JT : return "XCoreISD::BR_JT";
case XCoreISD::BR_JT32 : return "XCoreISD::BR_JT32";
+ case XCoreISD::FRAME_TO_ARGS_OFFSET : return "XCoreISD::FRAME_TO_ARGS_OFFSET";
case XCoreISD::MEMBARRIER : return "XCoreISD::MEMBARRIER";
default : return NULL;
}
@@ -153,6 +154,7 @@ XCoreTargetLowering::XCoreTargetLowering
// Exception handling
setExceptionPointerRegister(XCore::R0);
setExceptionSelectorRegister(XCore::R1);
+ setOperationAction(ISD::FRAME_TO_ARGS_OFFSET, MVT::i32, Custom);
// Atomic operations
setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
@@ -213,6 +215,7 @@ LowerOperation(SDValue Op, SelectionDAG
case ISD::SUB: return ExpandADDSUB(Op.getNode(), DAG);
case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
+ case ISD::FRAME_TO_ARGS_OFFSET: return LowerFRAME_TO_ARGS_OFFSET(Op, DAG);
case ISD::INIT_TRAMPOLINE: return LowerINIT_TRAMPOLINE(Op, DAG);
case ISD::ADJUST_TRAMPOLINE: return LowerADJUST_TRAMPOLINE(Op, DAG);
case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
@@ -827,6 +830,15 @@ LowerRETURNADDR(SDValue Op, SelectionDAG
}
SDValue XCoreTargetLowering::
+LowerFRAME_TO_ARGS_OFFSET(SDValue Op, SelectionDAG &DAG) const {
+ // This node represents offset from frame pointer to first on-stack argument.
+ // This is needed for correct stack adjustment during unwind.
+ // However, we don't know the offset until after the frame has be finalised.
+ // This is done during the XCoreFTAOElim pass.
+ return DAG.getNode(XCoreISD::FRAME_TO_ARGS_OFFSET, SDLoc(Op), MVT::i32);
+}
+
+SDValue XCoreTargetLowering::
LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const {
return Op.getOperand(0);
}
Modified: llvm/trunk/lib/Target/XCore/XCoreISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelLowering.h?rev=198614&r1=198613&r2=198614&view=diff
==============================================================================
--- llvm/trunk/lib/Target/XCore/XCoreISelLowering.h (original)
+++ llvm/trunk/lib/Target/XCore/XCoreISelLowering.h Mon Jan 6 08:21:00 2014
@@ -72,6 +72,9 @@ namespace llvm {
// Jumptable branch using long branches for each entry.
BR_JT32,
+ // Offset from frame pointer to the first (possible) on-stack argument
+ FRAME_TO_ARGS_OFFSET,
+
// Memory barrier.
MEMBARRIER
};
@@ -158,6 +161,7 @@ namespace llvm {
SDValue LowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerFRAME_TO_ARGS_OFFSET(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;
Modified: llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td?rev=198614&r1=198613&r2=198614&view=diff
==============================================================================
--- llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td (original)
+++ llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td Mon Jan 6 08:21:00 2014
@@ -56,6 +56,9 @@ def dprelwrapper : SDNode<"XCoreISD::DPR
def cprelwrapper : SDNode<"XCoreISD::CPRelativeWrapper", SDT_XCoreAddress,
[]>;
+def frametoargsoffset : SDNode<"XCoreISD::FRAME_TO_ARGS_OFFSET", SDTIntLeaf,
+ []>;
+
def SDT_XCoreStwsp : SDTypeProfile<0, 2, [SDTCisInt<1>]>;
def XCoreStwsp : SDNode<"XCoreISD::STWSP", SDT_XCoreStwsp,
[SDNPHasChain, SDNPMayStore]>;
@@ -326,6 +329,11 @@ def ADJCALLSTACKUP : PseudoInstXCore<(ou
[(callseq_end timm:$amt1, timm:$amt2)]>;
}
+let isReMaterializable = 1 in
+def FRAME_TO_ARGS_OFFSET : PseudoInstXCore<(outs GRRegs:$dst), (ins),
+ "# FRAME_TO_ARGS_OFFSET $dst",
+ [(set GRRegs:$dst, (frametoargsoffset))]>;
+
def LDWFI : PseudoInstXCore<(outs GRRegs:$dst), (ins MEMii:$addr),
"# LDWFI $dst, $addr",
[(set GRRegs:$dst, (load ADDRspii:$addr))]>;
Modified: llvm/trunk/lib/Target/XCore/XCoreTargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreTargetMachine.cpp?rev=198614&r1=198613&r2=198614&view=diff
==============================================================================
--- llvm/trunk/lib/Target/XCore/XCoreTargetMachine.cpp (original)
+++ llvm/trunk/lib/Target/XCore/XCoreTargetMachine.cpp Mon Jan 6 08:21:00 2014
@@ -48,6 +48,7 @@ public:
virtual bool addPreISel();
virtual bool addInstSelector();
+ virtual bool addPreEmitPass();
};
} // namespace
@@ -65,6 +66,11 @@ bool XCorePassConfig::addInstSelector()
return false;
}
+bool XCorePassConfig::addPreEmitPass() {
+ addPass(createXCoreFrameToArgsOffsetEliminationPass());
+ return false;
+}
+
// Force static initialization.
extern "C" void LLVMInitializeXCoreTarget() {
RegisterTargetMachine<XCoreTargetMachine> X(TheXCoreTarget);
Modified: llvm/trunk/test/CodeGen/XCore/llvm-intrinsics.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/llvm-intrinsics.ll?rev=198614&r1=198613&r2=198614&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/XCore/llvm-intrinsics.ll (original)
+++ llvm/trunk/test/CodeGen/XCore/llvm-intrinsics.ll Mon Jan 6 08:21:00 2014
@@ -44,3 +44,29 @@ entry:
%1 = call i8* @llvm.returnaddress(i32 0)
ret i8* %1
}
+
+; test FRAME_TO_ARGS_OFFSET lowering
+declare i8* @llvm.eh.dwarf.cfa(i32) nounwind
+define i8* @FTAO0() nounwind {
+entry:
+; CHECK-LABEL: FTAO0
+; CHECK: ldc r0, 0
+; CHECK-NEXT: ldaw r1, sp[0]
+; CHECK-NEXT: add r0, r1, r0
+; CHECK-NEXT: retsp 0
+ %0 = call i8* @llvm.eh.dwarf.cfa(i32 0)
+ ret i8* %0
+}
+
+define i8* @FTAO1() nounwind {
+entry:
+; CHECK-LABEL: FTAO1
+; CHECK: entsp 100
+; CHECK-NEXT: ldc r0, 400
+; CHECK-NEXT: ldaw r1, sp[0]
+; CHECK-NEXT: add r0, r1, r0
+; CHECK-NEXT: retsp 100
+ %0 = alloca [100 x i32]
+ %1 = call i8* @llvm.eh.dwarf.cfa(i32 0)
+ ret i8* %1
+}
More information about the llvm-commits
mailing list