[llvm] r277020 - [Hexagon] Insert CFI instructions before throwing calls

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 28 12:13:46 PDT 2016


Author: kparzysz
Date: Thu Jul 28 14:13:46 2016
New Revision: 277020

URL: http://llvm.org/viewvc/llvm-project?rev=277020&view=rev
Log:
[Hexagon] Insert CFI instructions before throwing calls

Normally, CFI instructions should be inserted after allocframe, but
if allocframe is in the same packet with a call, the CFI instructions
should be inserted before that packet.

Added:
    llvm/trunk/test/CodeGen/Hexagon/packetize-cfi-location.ll
Modified:
    llvm/trunk/lib/Target/Hexagon/HexagonFrameLowering.cpp

Modified: llvm/trunk/lib/Target/Hexagon/HexagonFrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonFrameLowering.cpp?rev=277020&r1=277019&r2=277020&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonFrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonFrameLowering.cpp Thu Jul 28 14:13:46 2016
@@ -734,32 +734,43 @@ bool HexagonFrameLowering::updateExitPat
 
 
 namespace {
-  bool IsAllocFrame(MachineBasicBlock::const_iterator It) {
-    if (!It->isBundle())
-      return It->getOpcode() == Hexagon::S2_allocframe;
-    auto End = It->getParent()->instr_end();
-    MachineBasicBlock::const_instr_iterator I = It.getInstrIterator();
-    while (++I != End && I->isBundled())
-      if (I->getOpcode() == Hexagon::S2_allocframe)
-        return true;
-    return false;
-  }
-
-  MachineBasicBlock::iterator FindAllocFrame(MachineBasicBlock &B) {
-    for (auto &I : B)
-      if (IsAllocFrame(I))
-        return I;
-    return B.end();
+  Optional<MachineBasicBlock::iterator> findCFILocation(MachineBasicBlock &B) {
+    // The CFI instructions need to be inserted right after allocframe.
+    // An exception to this is a situation where allocframe is bundled
+    // with a call: then the CFI instructions need to be inserted before
+    // the packet with the allocframe+call (in case the call throws an
+    // exception).
+    auto End = B.instr_end();
+
+    for (MachineInstr &I : B) {
+      MachineBasicBlock::iterator It = I.getIterator();
+      if (!I.isBundle()) {
+        if (I.getOpcode() == Hexagon::S2_allocframe)
+          return std::next(It);
+        continue;
+      }
+      // I is a bundle.
+      bool HasCall = false, HasAllocFrame = false;
+      auto T = It.getInstrIterator();
+      while (++T != End && T->isBundled()) {
+        if (T->getOpcode() == Hexagon::S2_allocframe)
+          HasAllocFrame = true;
+        else if (T->isCall())
+          HasCall = true;
+      }
+      if (HasAllocFrame)
+        return HasCall ? It : std::next(It);
+    }
+    return None;
   }
 }
 
 
 void HexagonFrameLowering::insertCFIInstructions(MachineFunction &MF) const {
   for (auto &B : MF) {
-    auto AF = FindAllocFrame(B);
-    if (AF == B.end())
-      continue;
-    insertCFIInstructionsAt(B, ++AF);
+    auto At = findCFILocation(B);
+    if (At.hasValue())
+      insertCFIInstructionsAt(B, At.getValue());
   }
 }
 

Added: llvm/trunk/test/CodeGen/Hexagon/packetize-cfi-location.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/packetize-cfi-location.ll?rev=277020&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/packetize-cfi-location.ll (added)
+++ llvm/trunk/test/CodeGen/Hexagon/packetize-cfi-location.ll Thu Jul 28 14:13:46 2016
@@ -0,0 +1,72 @@
+; RUN: llc -march=hexagon < %s | FileCheck %s
+
+target triple = "hexagon"
+%type.0 = type { i32, i8**, i32, i32, i32 }
+
+; Check that CFI is before the packet with call+allocframe.
+; CHECK-LABEL: danny:
+; CHECK: cfi_def_cfa
+; CHECK: call throw
+; CHECK-NEXT: allocframe
+
+; Expect packet:
+; {
+;   call throw
+;   allocframe(#0)
+; }
+
+define i8* @danny(%type.0* %p0, i32 %p1) #0 {
+entry:
+  %t0 = getelementptr inbounds %type.0, %type.0* %p0, i32 0, i32 4
+  %t1 = load i32, i32* %t0, align 4
+  %th = icmp ugt i32 %t1, %p1
+  br i1 %th, label %if.end, label %if.then
+
+if.then:                                          ; preds = %entry
+  tail call void @throw(%type.0* nonnull %p0)
+  unreachable
+
+if.end:                                           ; preds = %entry
+  %t6 = getelementptr inbounds %type.0, %type.0* %p0, i32 0, i32 3
+  %t2 = load i32, i32* %t6, align 4
+  %t9 = add i32 %t2, %p1
+  %ta = lshr i32 %t9, 4
+  %tb = and i32 %t9, 15
+  %t7 = getelementptr inbounds %type.0, %type.0* %p0, i32 0, i32 2
+  %t3 = load i32, i32* %t7, align 4
+  %tc = icmp ult i32 %ta, %t3
+  %td = select i1 %tc, i32 0, i32 %t3
+  %te = sub i32 %ta, %td
+  %t8 = getelementptr inbounds %type.0, %type.0* %p0, i32 0, i32 1
+  %t4 = load i8**, i8*** %t8, align 4
+  %tf = getelementptr inbounds i8*, i8** %t4, i32 %te
+  %t5 = load i8*, i8** %tf, align 4
+  %tg = getelementptr inbounds i8, i8* %t5, i32 %tb
+  ret i8* %tg
+}
+
+; Check that CFI is after allocframe.
+; CHECK-LABEL: sammy:
+; CHECK: allocframe
+; CHECK: cfi_def_cfa
+
+define void @sammy(%type.0* %p0, i32 %p1) #0 {
+entry:
+  %t0 = icmp sgt i32 %p1, 0
+  br i1 %t0, label %if.then, label %if.else
+if.then:
+  call void @throw(%type.0* nonnull %p0)
+  br label %if.end
+if.else:
+  call void @nothrow() #2
+  br label %if.end
+if.end:
+  ret void
+}
+
+declare void @throw(%type.0*) #1
+declare void @nothrow() #2
+
+attributes #0 = { "target-cpu"="hexagonv55" }
+attributes #1 = { noreturn "target-cpu"="hexagonv55" }
+attributes #2 = { nounwind "target-cpu"="hexagonv55" }




More information about the llvm-commits mailing list