From de189be53f5831737f38e720f10dbcdcce6876c6 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 30 Nov 2010 18:12:52 +0000 Subject: [PATCH] add TLI support indicating that jumps are more expensive than logical operations and use this to disable a specific optimization. Patch by Micah Villmow! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120435 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetLowering.h | 20 ++++++++++++++++++- .../SelectionDAG/SelectionDAGBuilder.cpp | 4 +++- lib/CodeGen/SelectionDAG/TargetLowering.cpp | 1 + 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 75e5325524e..b450f42752a 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -125,6 +125,10 @@ public: /// srl/add/sra. bool isPow2DivCheap() const { return Pow2DivIsCheap; } + /// isJumpExpensive() - Return true if Flow Control is an expensive operation + /// that should be avoided. + bool isJumpExpensive() const { return JumpIsExpensive; } + /// getSetCCResultType - Return the ValueType of the result of SETCC /// operations. Also used to obtain the target's preferred type for /// the condition operand of SELECT and BRCOND nodes. In the case of @@ -1013,7 +1017,16 @@ protected: /// SelectIsExpensive - Tells the code generator not to expand operations /// into sequences that use the select operations if possible. - void setSelectIsExpensive() { SelectIsExpensive = true; } + void setSelectIsExpensive(bool isExpensive = true) { + SelectIsExpensive = isExpensive; + } + + /// JumpIsExpensive - Tells the code generator not to expand sequence of + /// operations into a seperate sequences that increases the amount of + /// flow control. + void setJumpIsExpensive(bool isExpensive = true) { + JumpIsExpensive = isExpensive; + } /// setIntDivIsCheap - Tells the code generator that integer divide is /// expensive, and if possible, should be replaced by an alternate sequence @@ -1597,6 +1610,11 @@ private: /// it. bool Pow2DivIsCheap; + /// JumpIsExpensive - Tells the code generator that it shouldn't generate + /// extra flow control instructions and should attempt to combine flow + /// control instructions via predication. + bool JumpIsExpensive; + /// UseUnderscoreSetJmp - This target prefers to use _setjmp to implement /// llvm.setjmp. Defaults to false. bool UseUnderscoreSetJmp; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index d00643f1f18..6dfc6b53c71 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1403,6 +1403,7 @@ void SelectionDAGBuilder::visitBr(const BranchInst &I) { // If this is a series of conditions that are or'd or and'd together, emit // this as a sequence of branches instead of setcc's with and/or operations. + // As long as jumps are not expensive, this should improve performance. // For example, instead of something like: // cmp A, B // C = seteq @@ -1417,7 +1418,8 @@ void SelectionDAGBuilder::visitBr(const BranchInst &I) { // jle foo // if (const BinaryOperator *BOp = dyn_cast(CondVal)) { - if (BOp->hasOneUse() && + if (!TLI.isJumpExpensive() && + BOp->hasOneUse() && (BOp->getOpcode() == Instruction::And || BOp->getOpcode() == Instruction::Or)) { FindMergedConditions(BOp, Succ0MBB, Succ1MBB, BrMBB, BrMBB, diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 12ca9291d99..b2c2dbb927a 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -572,6 +572,7 @@ TargetLowering::TargetLowering(const TargetMachine &tm, SelectIsExpensive = false; IntDivIsCheap = false; Pow2DivIsCheap = false; + JumpIsExpensive = false; StackPointerRegisterToSaveRestore = 0; ExceptionPointerRegister = 0; ExceptionSelectorRegister = 0; -- 2.34.1