LLVM 20.0.0git
Classes | Macros | Typedefs | Functions | Variables
Reassociate.cpp File Reference
#include "llvm/Transforms/Scalar/Reassociate.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h"
#include <algorithm>
#include <cassert>
#include <utility>

Go to the source code of this file.

Classes

class  llvm::reassociate::XorOpnd
 Utility class representing a non-constant Xor-operand. More...
 

Macros

#define DEBUG_TYPE   "reassociate"
 

Typedefs

using RepeatedValue = std::pair< Value *, uint64_t >
 

Functions

 STATISTIC (NumChanged, "Number of insts reassociated")
 
 STATISTIC (NumAnnihil, "Number of expr tree annihilated")
 
 STATISTIC (NumFactor, "Number of multiplies factored")
 
static void PrintOps (Instruction *I, const SmallVectorImpl< ValueEntry > &Ops)
 Print out the expression identified in the Ops list.
 
static bool hasFPAssociativeFlags (Instruction *I)
 Return true if I is an instruction with the FastMathFlags that are needed for general reassociation set.
 
static BinaryOperatorisReassociableOp (Value *V, unsigned Opcode)
 Return true if V is an instruction of the specified opcode and if it only has one use.
 
static BinaryOperatorisReassociableOp (Value *V, unsigned Opcode1, unsigned Opcode2)
 
static BinaryOperatorCreateAdd (Value *S1, Value *S2, const Twine &Name, BasicBlock::iterator InsertBefore, Value *FlagsOp)
 
static BinaryOperatorCreateMul (Value *S1, Value *S2, const Twine &Name, BasicBlock::iterator InsertBefore, Value *FlagsOp)
 
static InstructionCreateNeg (Value *S1, const Twine &Name, BasicBlock::iterator InsertBefore, Value *FlagsOp)
 
static BinaryOperatorLowerNegateToMultiply (Instruction *Neg)
 Replace 0-X with X*-1.
 
static bool LinearizeExprTree (Instruction *I, SmallVectorImpl< RepeatedValue > &Ops, ReassociatePass::OrderedSet &ToRedo, reassociate::OverflowTracking &Flags)
 Given an associative binary expression, return the leaf nodes in Ops along with their weights (how many times the leaf occurs).
 
static ValueNegateValue (Value *V, Instruction *BI, ReassociatePass::OrderedSet &ToRedo)
 Insert instructions before the instruction pointed to by BI, that computes the negative version of the value specified.
 
static bool isLoadCombineCandidate (Instruction *Or)
 
static bool shouldConvertOrWithNoCommonBitsToAdd (Instruction *Or)
 Return true if it may be profitable to convert this (X|Y) into (X+Y).
 
static BinaryOperatorconvertOrWithNoCommonBitsToAdd (Instruction *Or)
 If we have (X|Y), and iff X and Y have no common bits set, transform this into (X+Y) to allow arithmetics reassociation.
 
static bool ShouldBreakUpSubtract (Instruction *Sub)
 Return true if we should break up this subtract of X-Y into (X + -Y).
 
static BinaryOperatorBreakUpSubtract (Instruction *Sub, ReassociatePass::OrderedSet &ToRedo)
 If we have (X-Y), and if either X is an add, or if this is only used by an add, transform this into (X+(0-Y)) to promote better reassociation.
 
static BinaryOperatorConvertShiftToMul (Instruction *Shl)
 If this is a shift of a reassociable multiply or is used by one, change this into a multiply by a constant to assist with further reassociation.
 
static unsigned FindInOperandList (const SmallVectorImpl< ValueEntry > &Ops, unsigned i, Value *X)
 Scan backwards and forwards among values with the same rank as element i to see if X exists.
 
static ValueEmitAddTreeOfValues (BasicBlock::iterator It, SmallVectorImpl< WeakTrackingVH > &Ops)
 Emit a tree of add instructions, summing Ops together and returning the result.
 
static void FindSingleUseMultiplyFactors (Value *V, SmallVectorImpl< Value * > &Factors)
 If V is a single-use multiply, recursively add its operands as factors, otherwise add V to the list of factors.
 
static ValueOptimizeAndOrXor (unsigned Opcode, SmallVectorImpl< ValueEntry > &Ops)
 Optimize a series of operands to an 'and', 'or', or 'xor' instruction.
 
static ValuecreateAndInstr (BasicBlock::iterator InsertBefore, Value *Opnd, const APInt &ConstOpnd)
 Helper function of CombineXorOpnd().
 
static bool collectMultiplyFactors (SmallVectorImpl< ValueEntry > &Ops, SmallVectorImpl< Factor > &Factors)
 Build up a vector of value/power pairs factoring a product.
 
static ValuebuildMultiplyTree (IRBuilderBase &Builder, SmallVectorImpl< Value * > &Ops)
 Build a tree of multiplies, computing the product of Ops.
 
static void getNegatibleInsts (Value *V, SmallVectorImpl< Instruction * > &Candidates)
 Recursively analyze an expression to build a list of instructions that have negative floating-point constant operands.
 
 INITIALIZE_PASS (ReassociateLegacyPass, "reassociate", "Reassociate expressions", false, false) FunctionPass *llvm
 

Variables

static cl::opt< boolUseCSELocalOpt (DEBUG_TYPE "-use-cse-local", cl::desc("Only reorder expressions within a basic block " "when exposing CSE opportunities"), cl::init(true), cl::Hidden)
 

Macro Definition Documentation

◆ DEBUG_TYPE

#define DEBUG_TYPE   "reassociate"

Definition at line 68 of file Reassociate.cpp.

Typedef Documentation

◆ RepeatedValue

using RepeatedValue = std::pair<Value *, uint64_t>

Definition at line 305 of file Reassociate.cpp.

Function Documentation

◆ BreakUpSubtract()

static BinaryOperator * BreakUpSubtract ( Instruction Sub,
ReassociatePass::OrderedSet ToRedo 
)
static

If we have (X-Y), and if either X is an add, or if this is only used by an add, transform this into (X+(0-Y)) to promote better reassociation.

Definition at line 1009 of file Reassociate.cpp.

References CreateAdd(), llvm::dbgs(), llvm::Instruction::getDebugLoc(), llvm::ilist_node_impl< OptionsT >::getIterator(), llvm::Constant::getNullValue(), llvm::User::getOperand(), llvm::Value::getType(), LLVM_DEBUG, NegateValue(), llvm::Value::replaceAllUsesWith(), and llvm::User::setOperand().

◆ buildMultiplyTree()

static Value * buildMultiplyTree ( IRBuilderBase Builder,
SmallVectorImpl< Value * > &  Ops 
)
static

◆ collectMultiplyFactors()

static bool collectMultiplyFactors ( SmallVectorImpl< ValueEntry > &  Ops,
SmallVectorImpl< Factor > &  Factors 
)
static

Build up a vector of value/power pairs factoring a product.

Given a series of multiplication operands, build a vector of factors and the powers each is raised to when forming the final product. Sort them in the order of descending power.

 (x*x)          -> [(x, 2)]
((x*x)*x)       -> [(x, 3)]

((((x*y)*x)*y)*x) -> [(x, 3), (y, 2)]

Returns
Whether any factors have a power greater than one.

Definition at line 1728 of file Reassociate.cpp.

References assert(), llvm::SmallVectorTemplateCommon< T, typename >::begin(), llvm::SmallVectorImpl< T >::erase(), Idx, LHS, llvm::SmallVectorTemplateBase< T, bool >::push_back(), RHS, llvm::SmallVectorBase< Size_T >::size(), Size, and llvm::stable_sort().

◆ convertOrWithNoCommonBitsToAdd()

static BinaryOperator * convertOrWithNoCommonBitsToAdd ( Instruction Or)
static

If we have (X|Y), and iff X and Y have no common bits set, transform this into (X+Y) to allow arithmetics reassociation.

Definition at line 962 of file Reassociate.cpp.

References CreateAdd(), llvm::dbgs(), LLVM_DEBUG, and llvm::Or.

◆ ConvertShiftToMul()

static BinaryOperator * ConvertShiftToMul ( Instruction Shl)
static

◆ CreateAdd()

static BinaryOperator * CreateAdd ( Value S1,
Value S2,
const Twine Name,
BasicBlock::iterator  InsertBefore,
Value FlagsOp 
)
static

◆ createAndInstr()

static Value * createAndInstr ( BasicBlock::iterator  InsertBefore,
Value Opnd,
const APInt ConstOpnd 
)
static

Helper function of CombineXorOpnd().

It creates a bitwise-and instruction with the given two operands, and return the resulting instruction. There are two special cases: 1) if the constant operand is 0, it will return NULL. 2) if the constant is ~0, the symbolic operand will be returned.

Definition at line 1242 of file Reassociate.cpp.

References llvm::Value::getType(), I, llvm::APInt::isAllOnes(), and llvm::APInt::isZero().

◆ CreateMul()

static BinaryOperator * CreateMul ( Value S1,
Value S2,
const Twine Name,
BasicBlock::iterator  InsertBefore,
Value FlagsOp 
)
static

◆ CreateNeg()

static Instruction * CreateNeg ( Value S1,
const Twine Name,
BasicBlock::iterator  InsertBefore,
Value FlagsOp 
)
static

◆ EmitAddTreeOfValues()

static Value * EmitAddTreeOfValues ( BasicBlock::iterator  It,
SmallVectorImpl< WeakTrackingVH > &  Ops 
)
static

Emit a tree of add instructions, summing Ops together and returning the result.

Insert the tree before I.

Definition at line 1090 of file Reassociate.cpp.

References llvm::SmallVectorTemplateCommon< T, typename >::back(), CreateAdd(), EmitAddTreeOfValues(), llvm::SmallVectorImpl< T >::pop_back_val(), and llvm::SmallVectorBase< Size_T >::size().

Referenced by EmitAddTreeOfValues().

◆ FindInOperandList()

static unsigned FindInOperandList ( const SmallVectorImpl< ValueEntry > &  Ops,
unsigned  i,
Value X 
)
static

Scan backwards and forwards among values with the same rank as element i to see if X exists.

If X does not exist, return i. This is useful when scanning for 'x' when we see '-x' because they both get the same rank.

Definition at line 1064 of file Reassociate.cpp.

References llvm::SmallVectorBase< Size_T >::size(), and X.

Referenced by OptimizeAndOrXor().

◆ FindSingleUseMultiplyFactors()

static void FindSingleUseMultiplyFactors ( Value V,
SmallVectorImpl< Value * > &  Factors 
)
static

If V is a single-use multiply, recursively add its operands as factors, otherwise add V to the list of factors.

Ops is the top-level list of add operands we're trying to factor.

Definition at line 1176 of file Reassociate.cpp.

References FindSingleUseMultiplyFactors(), llvm::User::getOperand(), isReassociableOp(), and llvm::SmallVectorTemplateBase< T, bool >::push_back().

Referenced by FindSingleUseMultiplyFactors().

◆ getNegatibleInsts()

static void getNegatibleInsts ( Value V,
SmallVectorImpl< Instruction * > &  Candidates 
)
static

Recursively analyze an expression to build a list of instructions that have negative floating-point constant operands.

The caller can then transform the list to create positive constants for better reassociation and CSE.

Definition at line 2017 of file Reassociate.cpp.

References llvm::CallingConv::C, llvm::dbgs(), getNegatibleInsts(), I, LLVM_DEBUG, llvm::PatternMatch::m_APFloat(), llvm::PatternMatch::m_Constant(), llvm::PatternMatch::m_Instruction(), llvm::PatternMatch::m_OneUse(), llvm::PatternMatch::match(), and llvm::SmallVectorTemplateBase< T, bool >::push_back().

Referenced by getNegatibleInsts().

◆ hasFPAssociativeFlags()

static bool hasFPAssociativeFlags ( Instruction I)
static

Return true if I is an instruction with the FastMathFlags that are needed for general reassociation set.

This is not the same as testing Instruction::isAssociative() because it includes operations like fsub. (This routine is only intended to be called for floating-point operations.)

Definition at line 156 of file Reassociate.cpp.

References assert(), and I.

Referenced by isReassociableOp(), and LinearizeExprTree().

◆ INITIALIZE_PASS()

INITIALIZE_PASS ( ReassociateLegacyPass  ,
"reassociate"  ,
"Reassociate expressions"  ,
false  ,
false   
)

Definition at line 2657 of file Reassociate.cpp.

◆ isLoadCombineCandidate()

static bool isLoadCombineCandidate ( Instruction Or)
static

◆ isReassociableOp() [1/2]

static BinaryOperator * isReassociableOp ( Value V,
unsigned  Opcode 
)
static

Return true if V is an instruction of the specified opcode and if it only has one use.

Definition at line 163 of file Reassociate.cpp.

References hasFPAssociativeFlags().

◆ isReassociableOp() [2/2]

static BinaryOperator * isReassociableOp ( Value V,
unsigned  Opcode1,
unsigned  Opcode2 
)
static

Definition at line 171 of file Reassociate.cpp.

References hasFPAssociativeFlags().

◆ LinearizeExprTree()

static bool LinearizeExprTree ( Instruction I,
SmallVectorImpl< RepeatedValue > &  Ops,
ReassociatePass::OrderedSet ToRedo,
reassociate::OverflowTracking Flags 
)
static

Given an associative binary expression, return the leaf nodes in Ops along with their weights (how many times the leaf occurs).

The original expression is the same as (Ops[0].first op Ops[0].first op ... Ops[0].first) <- Ops[0].second times op (Ops[1].first op Ops[1].first op ... Ops[1].first) <- Ops[1].second times op ... op (Ops[N].first op Ops[N].first op ... Ops[N].first) <- Ops[N].second times

Note that the values Ops[0].first, ..., Ops[N].first are all distinct.

This routine may modify the function, in which case it returns 'true'. The changes it makes may well be destructive, changing the value computed by 'I' to something completely different. Thus if the routine returns 'true' then you MUST either replace I with a new expression computed from the Ops array, or use RewriteExprTree to put the values back in.

A leaf node is either not a binary operation of the same kind as the root node 'I' (i.e. is not a binary operator at all, or is, but with a different opcode), or is the same kind of binary operator but has a use which either does not belong to the expression, or does belong to the expression but is a leaf node. Every leaf node has at least one use that is a non-leaf node of the expression, while for non-leaf nodes (except for the root 'I') every use is a non-leaf node of the expression.

For example: expression graph node names

      +        |        I
     / \       |
    +   +      |      A,  B
   / \ / \     |
  *   +   *    |    C,  D,  E
 / \ / \ / \   |
    +   *      |      F,  G

The leaf nodes are C, E, F and G. The Ops array will contain (maybe not in that order) (C, 1), (E, 1), (F, 2), (G, 2).

The expression is maximal: if some instruction is a binary operator of the same kind as 'I', and all of its uses are non-leaf nodes of the expression, then the instruction also belongs to the expression, is not a leaf node of it, and its operands also belong to the expression (but may be leaf nodes).

NOTE: This routine will set operands of non-leaf non-root nodes to undef in order to ensure that every non-root node in the expression has exactly one use by a non-leaf node of the expression. This destruction means that the caller MUST either replace 'I' with a new expression or use something like RewriteExprTree to put the values back in if the routine indicates that it made a change by returning 'true'.

In the above example either the right operand of A or the left operand of B will be replaced by undef. If it is B's operand then this gives:

                +        |        I
               / \       |
              +   +      |      A,  B - operand of B replaced with undef
             / \   \     |
            *   +   *    |    C,  D,  E
           / \ / \ / \   |
              +   *      |      F,  G

Note that such undef operands can only be reached by passing through 'I'. For example, if you visit operands recursively starting from a leaf node then you will never see such an undef operand unless you get back to 'I', which requires passing through a phi node.

Note that this routine may also mutate binary operators of the wrong type that have all uses inside the expression (i.e. only used by non-leaf nodes of the expression) if it can turn them into binary operators of the right type and thus make the expression bigger.

Definition at line 380 of file Reassociate.cpp.

References assert(), llvm::SmallPtrSetImpl< PtrType >::count(), llvm::dbgs(), DL, llvm::SmallVectorImpl< T >::emplace_back(), llvm::SmallVectorBase< Size_T >::empty(), llvm::ConstantExpr::getBinOpIdentity(), getOpcode(), hasFPAssociativeFlags(), I, llvm::SetVector< T, Vector, Set, N >::insert(), llvm::SmallPtrSetImpl< PtrType >::insert(), llvm::isKnownNonNegative(), llvm::isKnownNonZero(), isReassociableOp(), LLVM_DEBUG, LowerNegateToMultiply(), llvm::PatternMatch::m_FNeg(), llvm::PatternMatch::m_Instruction(), llvm::PatternMatch::m_Neg(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), llvm::Mul, llvm::SmallVectorImpl< T >::pop_back_val(), and llvm::SmallVectorTemplateBase< T, bool >::push_back().

◆ LowerNegateToMultiply()

static BinaryOperator * LowerNegateToMultiply ( Instruction Neg)
static

◆ NegateValue()

static Value * NegateValue ( Value V,
Instruction BI,
ReassociatePass::OrderedSet ToRedo 
)
static

◆ OptimizeAndOrXor()

static Value * OptimizeAndOrXor ( unsigned  Opcode,
SmallVectorImpl< ValueEntry > &  Ops 
)
static

Optimize a series of operands to an 'and', 'or', or 'xor' instruction.

This optimizes based on identities. If it can be reduced to a single Value, it is returned, otherwise the Ops list is mutated as necessary.

Definition at line 1192 of file Reassociate.cpp.

References assert(), llvm::SmallVectorTemplateCommon< T, typename >::begin(), llvm::SmallVectorImpl< T >::erase(), FindInOperandList(), llvm::Constant::getAllOnesValue(), llvm::Constant::getNullValue(), llvm::PatternMatch::m_Not(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), llvm::SmallVectorBase< Size_T >::size(), and X.

◆ PrintOps()

static void PrintOps ( Instruction I,
const SmallVectorImpl< ValueEntry > &  Ops 
)
static

Print out the expression identified in the Ops list.

Definition at line 82 of file Reassociate.cpp.

References llvm::dbgs(), llvm::Instruction::getOpcodeName(), I, and llvm::SmallVectorBase< Size_T >::size().

◆ ShouldBreakUpSubtract()

static bool ShouldBreakUpSubtract ( Instruction Sub)
static

◆ shouldConvertOrWithNoCommonBitsToAdd()

static bool shouldConvertOrWithNoCommonBitsToAdd ( Instruction Or)
static

Return true if it may be profitable to convert this (X|Y) into (X+Y).

Definition at line 938 of file Reassociate.cpp.

References llvm::any_of(), isInteresting(), isReassociableOp(), and llvm::Or.

◆ STATISTIC() [1/3]

STATISTIC ( NumAnnihil  ,
"Number of expr tree annihilated"   
)

◆ STATISTIC() [2/3]

STATISTIC ( NumChanged  ,
"Number of insts reassociated"   
)

◆ STATISTIC() [3/3]

STATISTIC ( NumFactor  ,
"Number of multiplies factored"   
)

Variable Documentation

◆ UseCSELocalOpt

cl::opt< bool > UseCSELocalOpt(DEBUG_TYPE "-use-cse-local", cl::desc("Only reorder expressions within a basic block " "when exposing CSE opportunities"), cl::init(true), cl::Hidden) ( DEBUG_TYPE "-use-cse-local"  ,
cl::desc("Only reorder expressions within a basic block " "when exposing CSE opportunities")  ,
cl::init(true ,
cl::Hidden   
)
static