From 92b0a64906757ded834bc6e9f8915d889402f3c2 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 7 Dec 2013 01:49:19 +0000 Subject: [PATCH] Add a RequireStructuredCFG Field to TargetMachine. llvm-svn: 196634 --- llvm/docs/WritingAnLLVMBackend.rst | 6 ++++++ llvm/include/llvm/Target/TargetMachine.h | 4 ++++ llvm/lib/CodeGen/BranchFolding.cpp | 6 +++++- llvm/lib/CodeGen/MachineBasicBlock.cpp | 5 +++++ llvm/lib/CodeGen/Passes.cpp | 5 ++++- llvm/lib/Target/R600/AMDGPUTargetMachine.cpp | 1 + llvm/lib/Target/TargetMachine.cpp | 1 + llvm/test/CodeGen/R600/jump-address.ll | 2 +- 8 files changed, 27 insertions(+), 3 deletions(-) diff --git a/llvm/docs/WritingAnLLVMBackend.rst b/llvm/docs/WritingAnLLVMBackend.rst index 35a2d164a909..429f52a3526a 100644 --- a/llvm/docs/WritingAnLLVMBackend.rst +++ b/llvm/docs/WritingAnLLVMBackend.rst @@ -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 diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h index eed07065e812..c27ffdfcd77b 100644 --- a/llvm/include/llvm/Target/TargetMachine.h +++ b/llvm/include/llvm/Target/TargetMachine.h @@ -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; } diff --git a/llvm/lib/CodeGen/BranchFolding.cpp b/llvm/lib/CodeGen/BranchFolding.cpp index 9cd4208d6461..a4a3712de8be 100644 --- a/llvm/lib/CodeGen/BranchFolding.cpp +++ b/llvm/lib/CodeGen/BranchFolding.cpp @@ -83,7 +83,11 @@ INITIALIZE_PASS(BranchFolderPass, "branch-folder", bool BranchFolderPass::runOnMachineFunction(MachineFunction &MF) { TargetPassConfig *PassConfig = &getAnalysis(); - 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(), diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp index ca71e3bf8062..3d36dc18e38b 100644 --- a/llvm/lib/CodeGen/MachineBasicBlock.cpp +++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp @@ -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(); diff --git a/llvm/lib/CodeGen/Passes.cpp b/llvm/lib/CodeGen/Passes.cpp index f4ffd03ec3ea..db7021372bc2 100644 --- a/llvm/lib/CodeGen/Passes.cpp +++ b/llvm/lib/CodeGen/Passes.cpp @@ -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. diff --git a/llvm/lib/Target/R600/AMDGPUTargetMachine.cpp b/llvm/lib/Target/R600/AMDGPUTargetMachine.cpp index bc4f5d720ae2..b42728550aa3 100644 --- a/llvm/lib/Target/R600/AMDGPUTargetMachine.cpp +++ b/llvm/lib/Target/R600/AMDGPUTargetMachine.cpp @@ -72,6 +72,7 @@ AMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, StringRef TT, InstrInfo.reset(new SIInstrInfo(*this)); TLInfo.reset(new SITargetLowering(*this)); } + setRequiresStructuredCFG(true); initAsmInfo(); } diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp index 9ba78bce7f9c..a2350352071e 100644 --- a/llvm/lib/Target/TargetMachine.cpp +++ b/llvm/lib/Target/TargetMachine.cpp @@ -55,6 +55,7 @@ TargetMachine::TargetMachine(const Target &T, MCUseLoc(true), MCUseCFI(true), MCUseDwarfDirectory(false), + RequireStructuredCFG(false), Options(Options) { } diff --git a/llvm/test/CodeGen/R600/jump-address.ll b/llvm/test/CodeGen/R600/jump-address.ll index ae9c8bba4fd6..a1cd3882443a 100644 --- a/llvm/test/CodeGen/R600/jump-address.ll +++ b/llvm/test/CodeGen/R600/jump-address.ll @@ -1,6 +1,6 @@ ;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s -; CHECK: JUMP @3 +; CHECK: JUMP @6 ; CHECK: EXPORT ; CHECK-NOT: EXPORT