[llvm] r196085 - XCore target: Fix eliminateFrameIndex() to handle large frames

Robert Lytton robert at xmos.com
Mon Dec 2 02:18:19 PST 2013


Author: rlytton
Date: Mon Dec  2 04:18:19 2013
New Revision: 196085

URL: http://llvm.org/viewvc/llvm-project?rev=196085&view=rev
Log:
XCore target: Fix eliminateFrameIndex() to handle large frames

Large frame offsets are loaded from the ConstantPool.
Where possible, offsets are encoded using the smaller MKMSK instruction.
Large frame offsets can only be used when there is a frame-pointer.

Added:
    llvm/trunk/test/CodeGen/XCore/epilogue_prologue_fp.ll
Modified:
    llvm/trunk/lib/Target/XCore/XCoreRegisterInfo.cpp

Modified: llvm/trunk/lib/Target/XCore/XCoreRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreRegisterInfo.cpp?rev=196085&r1=196084&r2=196085&view=diff
==============================================================================
--- llvm/trunk/lib/Target/XCore/XCoreRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/XCore/XCoreRegisterInfo.cpp Mon Dec  2 04:18:19 2013
@@ -16,16 +16,19 @@
 #include "XCoreMachineFunctionInfo.h"
 #include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/RegisterScavenging.h"
+#include "llvm/IR/Constants.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/Type.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetFrameLowering.h"
 #include "llvm/Target/TargetInstrInfo.h"
@@ -244,14 +247,22 @@ XCoreRegisterInfo::eliminateFrameIndex(M
 void XCoreRegisterInfo::
 loadConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
             unsigned DstReg, int64_t Value, DebugLoc dl) const {
-  // TODO use mkmsk if possible.
-  if (!isImmU16(Value)) {
-    // TODO use constant pool.
-    report_fatal_error("loadConstant value too big " + Twine(Value));
-  }
-  int Opcode = isImmU6(Value) ? XCore::LDC_ru6 : XCore::LDC_lru6;
   const TargetInstrInfo &TII = *MBB.getParent()->getTarget().getInstrInfo();
-  BuildMI(MBB, I, dl, TII.get(Opcode), DstReg).addImm(Value);
+  if (isMask_32(Value)) {
+    int N = Log2_32(Value) + 1;
+    BuildMI(MBB, I, dl, TII.get(XCore::MKMSK_rus), DstReg).addImm(N);
+  } else if (isImmU16(Value)) {
+    int Opcode = isImmU6(Value) ? XCore::LDC_ru6 : XCore::LDC_lru6;
+    BuildMI(MBB, I, dl, TII.get(Opcode), DstReg).addImm(Value);
+    return;
+  } else {
+    MachineConstantPool *ConstantPool = MBB.getParent()->getConstantPool();
+    const Constant *C = ConstantInt::get(
+        Type::getInt32Ty(MBB.getParent()->getFunction()->getContext()), Value);
+    unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
+    BuildMI(MBB, I, dl, TII.get(XCore::LDWCP_lru6), DstReg)
+        .addConstantPoolIndex(Idx);
+  }
 }
 
 unsigned XCoreRegisterInfo::getFrameRegister(const MachineFunction &MF) const {

Added: llvm/trunk/test/CodeGen/XCore/epilogue_prologue_fp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/epilogue_prologue_fp.ll?rev=196085&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/XCore/epilogue_prologue_fp.ll (added)
+++ llvm/trunk/test/CodeGen/XCore/epilogue_prologue_fp.ll Mon Dec  2 04:18:19 2013
@@ -0,0 +1,42 @@
+; Functions with frames > 256K bytes require a frame pointer to access the stack.
+; At present, functions must be compiled using '-fno-omit-frame-pointer'.
+; RUN: llc < %s -march=xcore -disable-fp-elim | FileCheck %s
+
+declare void @f0(i32*)
+
+; CHECK: .section .cp.rodata.cst4,"aMc", at progbits,4
+; CHECK: .LCPI[[NUM:[0-9_]+]]:
+; CHECK: .long   99999
+; CHECK: .text
+; CHECK-LABEL:f1
+; CHECK:      entsp 65535
+; CHECK-NEXT: extsp 34465
+; CHECK-NEXT: stw r10, sp[1]
+; CHECK-NEXT: ldaw r10, sp[0]
+; CHECK-NEXT: ldw r1, cp[.LCPI[[NUM]]]
+; CHECK-NEXT: ldaw r0, r10[r1]
+; CHECK-NEXT: extsp 1
+; CHECK-NEXT: bl f0
+; CHECK-NEXT: ldaw sp, sp[1]
+; CHECK-NEXT: set sp, r10
+; CHECK-NEXT: ldw r10, sp[1]
+; CHECK-NEXT: ldaw sp, sp[65535]
+; CHECK-NEXT: retsp 34465
+define void @f1() nounwind {
+entry:
+  %0 = alloca [99998 x i32]
+  %1 = getelementptr inbounds [99998 x i32]* %0, i32 0, i32 99997
+  call void @f0(i32* %1)
+  ret void
+}
+
+; CHECK-LABEL:f2
+; CHECK:      mkmsk  [[REG:r[0-9]+]], 15
+; CHECK-NEXT: ldaw r0, r10{{\[}}[[REG]]{{\]}}
+define void @f2() nounwind {
+entry:
+  %0 = alloca [32768 x i32]
+  %1 = getelementptr inbounds [32768 x i32]* %0, i32 0, i32 32765
+  call void @f0(i32* %1)
+  ret void
+}





More information about the llvm-commits mailing list