[PATCH] ARM: Windows on ARM Hazard recognition support

Saleem Abdulrasool abdulras at fb.com
Tue Apr 1 16:07:31 PDT 2014


Hi t.p.northover, grosbach,

IMAGE_REL_ARM_MOV32T relocations require that the movw/movt pair relocation is
not split up and reordered.  We handle this in the ARM Hazard Recognizer by
tracking the previous machine instruction and the current one.  If the previous
one is a mov.w of an address entity, scan through the rest of the instructions
in the function to only permit the paired mov.t.  If only the low half of an
address is being loaded (i.e. mov.w without a mov.t) then the only downside of
this tracking is that we end up scanning the remainder of the function to detect
that no other instruction can be reordered around this point.

http://llvm-reviews.chandlerc.com/D3254

Files:
  lib/Target/ARM/ARMHazardRecognizer.cpp
  test/CodeGen/ARM/Windows/movw-movt-relocations.ll

Index: lib/Target/ARM/ARMHazardRecognizer.cpp
===================================================================
--- lib/Target/ARM/ARMHazardRecognizer.cpp
+++ lib/Target/ARM/ARMHazardRecognizer.cpp
@@ -11,6 +11,7 @@
 #include "ARMBaseInstrInfo.h"
 #include "ARMBaseRegisterInfo.h"
 #include "ARMSubtarget.h"
+#include "llvm/ADT/Triple.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/ScheduleDAG.h"
 #include "llvm/Target/TargetRegisterInfo.h"
@@ -31,12 +32,56 @@
   return false;
 }
 
+static bool IsAddress(const MachineOperand &MO) {
+  return MO.isGlobal() || MO.isSymbol() || MO.isCPI();
+}
+
+static bool IsAddressPair(const MachineOperand &MO0, const MachineOperand &MO1) {
+  if (MO0.getType() != MO1.getType())
+    return false;
+
+  switch (MO0.getType()) {
+  case MachineOperand::MO_ConstantPoolIndex:
+    if (MO0.getIndex() == MO1.getIndex())
+      break;
+    return false;
+  case MachineOperand::MO_GlobalAddress:
+    if (MO0.getGlobal() == MO1.getGlobal())
+      break;
+    return false;
+  case MachineOperand::MO_ExternalSymbol:
+    if (StringRef(MO0.getSymbolName()) == StringRef(MO1.getSymbolName()))
+      break;
+    return false;
+  default:
+    return false;
+  }
+  return MO0.getOffset() == MO1.getOffset();
+}
+
 ScheduleHazardRecognizer::HazardType
 ARMHazardRecognizer::getHazardType(SUnit *SU, int Stalls) {
   assert(Stalls == 0 && "ARM hazards don't support scoreboard lookahead");
 
   MachineInstr *MI = SU->getInstr();
 
+  const Triple TT(MI->getParent()->getParent()->getTarget().getTargetTriple());
+  if (TT.isOSWindows()) {
+    if (LastMI && LastMI->getOpcode() == ARM::t2MOVi16 &&
+        IsAddress(LastMI->getOperand(1))) {
+      // If there is a previous instruction of type mov.w of an address, there
+      // is a hazard for any instruction other than the mov.t that loads the
+      // high portion of the address as the Windows loader expects that the two
+      // instructions are contiguous.
+      assert(LastMI->getOperand(1).getTargetFlags() == ARMII::MO_LO16 &&
+             "expected low address load");
+      if (MI->getOpcode() == ARM::t2MOVTi16 &&
+          IsAddressPair(LastMI->getOperand(1), MI->getOperand(2)))
+        return NoHazard;
+      return Hazard;
+    }
+  }
+
   if (!MI->isDebugValue()) {
     // Look for special VMLA / VMLS hazards. A VMUL / VADD / VSUB following
     // a VMLA / VMLS will cause 4 cycle stall.
Index: test/CodeGen/ARM/Windows/movw-movt-relocations.ll
===================================================================
--- /dev/null
+++ test/CodeGen/ARM/Windows/movw-movt-relocations.ll
@@ -0,0 +1,28 @@
+; RUN: llc -mtriple=thumbv7-windows -o - %s \
+; RUN:   | FileCheck %s -check-prefix CHECK-WINDOWS
+
+; RUN: llc -mtriple=thumbv7-eabi -o - %s \
+; RUN:   | FileCheck %s -check-prefix CHECK-EABI
+
+ at i = common global i32 0, align 4
+ at j = common global i32 0, align 4
+
+; Function Attrs: nounwind optsize readonly
+define i32 @relocation(i32 %j, i32 %k) {
+entry:
+  %0 = load i32* @i, align 4
+  %1 = load i32* @j, align 4
+  %add = add nsw i32 %1, %0
+  ret i32 %add
+}
+
+; CHECK-WINDOWS: movw r[[i:[0-4]]], :lower16:i
+; CHECK-WINDOWS-NEXT: movt r[[i]], :upper16:i
+; CHECK-WINDOWS: movw r[[j:[0-4]]], :lower16:j
+; CHECK-WINDOWS-NEXT: movt r[[j]], :upper16:j
+
+; CHECK-EABI: movw r[[i:[0-4]]], :lower16:i
+; CHECK-EABI: movw r[[j:[0-4]]], :lower16:j
+; CHECK-EABI-NEXT: movt r[[i]], :upper16:i
+; CHECK-EABI-NEXT: movt r[[j]], :upper16:j
+
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3254.1.patch
Type: text/x-patch
Size: 3484 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140401/f26fc306/attachment.bin>


More information about the llvm-commits mailing list