Add a RequireStructuredCFG Field to TargetMachine.
authorVincent Lejeune <vljn@ovi.com>
Sat, 7 Dec 2013 01:49:19 +0000 (01:49 +0000)
committerVincent Lejeune <vljn@ovi.com>
Sat, 7 Dec 2013 01:49:19 +0000 (01:49 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@196634 91177308-0d34-0410-b5e6-96231b3b80d8

docs/WritingAnLLVMBackend.rst
include/llvm/Target/TargetMachine.h
lib/CodeGen/BranchFolding.cpp
lib/CodeGen/MachineBasicBlock.cpp
lib/CodeGen/Passes.cpp
lib/Target/R600/AMDGPUTargetMachine.cpp
lib/Target/TargetMachine.cpp
test/CodeGen/R600/jump-address.ll

index 35a2d164a909309106cf8a4fd77c70c10d9594cf..429f52a3526a6a1f1a9c2f215c80c07ed9cfcc97 100644 (file)
@@ -238,6 +238,12 @@ For some targets, you also need to support the following methods:
 * ``getTargetLowering()``
 * ``getJITInfo()``
 
+Some architectures, such as GPUs, do not support jumping to an arbitrary
+program location and implement branching using masked execution and loop using
+special instructions around the loop body. In order to avoid CFG modifications
+that introduce irreducible control flow not handled by such hardware, a target
+must call `setRequiresStructuredCFG(true)` when being initialized.
+
 In addition, the ``XXXTargetMachine`` constructor should specify a
 ``TargetDescription`` string that determines the data layout for the target
 machine, including characteristics such as pointer size, alignment, and
index eed07065e812189e2d934b6fb53229497ccf3c3f..c27ffdfcd77b3b74f0914e08162916eace43dd45 100644 (file)
@@ -88,6 +88,7 @@ protected: // Can only create subclasses.
   unsigned MCUseLoc : 1;
   unsigned MCUseCFI : 1;
   unsigned MCUseDwarfDirectory : 1;
+  unsigned RequireStructuredCFG : 1;
 
 public:
   virtual ~TargetMachine();
@@ -156,6 +157,9 @@ public:
     return 0;
   }
 
+  bool requiresStructuredCFG() const { return RequireStructuredCFG; }
+  void setRequiresStructuredCFG(bool Value) { RequireStructuredCFG = Value; }
+
   /// hasMCRelaxAll - Check whether all machine code instructions should be
   /// relaxed.
   bool hasMCRelaxAll() const { return MCRelaxAll; }
index 9cd4208d646142eb7cf1295e7a01b70f8619be00..a4a3712de8be18bb8240ece7a61e75cc78f42143 100644 (file)
@@ -83,7 +83,11 @@ INITIALIZE_PASS(BranchFolderPass, "branch-folder",
 
 bool BranchFolderPass::runOnMachineFunction(MachineFunction &MF) {
   TargetPassConfig *PassConfig = &getAnalysis<TargetPassConfig>();
-  BranchFolder Folder(PassConfig->getEnableTailMerge(), /*CommonHoist=*/true);
+  // TailMerge can create jump into if branches that make CFG irreducible for
+  // HW that requires structurized CFG.
+  bool EnableTailMerge = !MF.getTarget().requiresStructuredCFG() &&
+      PassConfig->getEnableTailMerge();
+  BranchFolder Folder(EnableTailMerge, /*CommonHoist=*/true);
   return Folder.OptimizeFunction(MF,
                                  MF.getTarget().getInstrInfo(),
                                  MF.getTarget().getRegisterInfo(),
index ca71e3bf80626a0bd947cf01ab0a1835f06fdcbd..3d36dc18e38b1eb22218970fe0c0e291205c1408 100644 (file)
@@ -677,6 +677,11 @@ MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {
   MachineFunction *MF = getParent();
   DebugLoc dl;  // FIXME: this is nowhere
 
+  // Performance might be harmed on HW that implements branching using exec mask
+  // where both sides of the branches are always executed.
+  if (MF->getTarget().requiresStructuredCFG())
+    return NULL;
+
   // We may need to update this's terminator, but we can't do that if
   // AnalyzeBranch fails. If this uses a jump table, we won't touch it.
   const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
index f4ffd03ec3eab071d7af4cea0ebdb5084907d4ef..db7021372bc2bbf2b8b89843522fd0f8c2c8a35e 100644 (file)
@@ -725,7 +725,10 @@ void TargetPassConfig::addMachineLateOptimization() {
     printAndVerify("After BranchFolding");
 
   // Tail duplication.
-  if (addPass(&TailDuplicateID))
+  // Note that duplicating tail just increases code size and degrades
+  // performance for targets that require Structured Control Flow.
+  // In addition it can also make CFG irreducible. Thus we disable it.
+  if (!TM->requiresStructuredCFG() && addPass(&TailDuplicateID))
     printAndVerify("After TailDuplicate");
 
   // Copy propagation.
index bc4f5d720ae20a642eef5ec085addf567cd90bd8..b42728550aa3961e0d3b2e75494cc7357a36cfbd 100644 (file)
@@ -72,6 +72,7 @@ AMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, StringRef TT,
     InstrInfo.reset(new SIInstrInfo(*this));
     TLInfo.reset(new SITargetLowering(*this));
   }
+  setRequiresStructuredCFG(true);
   initAsmInfo();
 }
 
index 9ba78bce7f9c6eee7d768165f33035c6d941ced3..a2350352071e5cdaba11d9e0ab2e52dc3f39c7fc 100644 (file)
@@ -55,6 +55,7 @@ TargetMachine::TargetMachine(const Target &T,
     MCUseLoc(true),
     MCUseCFI(true),
     MCUseDwarfDirectory(false),
+    RequireStructuredCFG(false),
     Options(Options) {
 }
 
index ae9c8bba4fd67b73ab44b295cd64c9b878c37f61..a1cd3882443a034f4801e1a58b79d98308c86202 100644 (file)
@@ -1,6 +1,6 @@
 ;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s
 
-; CHECK: JUMP @3
+; CHECK: JUMP @6
 ; CHECK: EXPORT
 ; CHECK-NOT: EXPORT