[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