//===- DIExpressionOptimizer.cpp - Constant folding of DIExpressions ------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file implements functions to constant fold DIExpressions. Which were // declared in DIExpressionOptimizer.h // //===----------------------------------------------------------------------===// #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/IR/DebugInfoMetadata.h" usingnamespacellvm; /// Returns true if the Op is a DW_OP_constu. static std::optional<uint64_t> isConstantVal(DIExpression::ExprOperand Op) { … } /// Returns true if an operation and operand result in a No Op. static bool isNeutralElement(uint64_t Op, uint64_t Val) { … } /// Try to fold \p Const1 and \p Const2 by applying \p Operator and returning /// the result, if there is an overflow, return a std::nullopt. static std::optional<uint64_t> foldOperationIfPossible(uint64_t Const1, uint64_t Const2, dwarf::LocationAtom Operator) { … } /// Returns true if the two operations \p Operator1 and \p Operator2 are /// commutative and can be folded. static bool operationsAreFoldableAndCommutative(dwarf::LocationAtom Operator1, dwarf::LocationAtom Operator2) { … } /// Consume one operator and its operand(s). static void consumeOneOperator(DIExpressionCursor &Cursor, uint64_t &Loc, const DIExpression::ExprOperand &Op) { … } /// Reset the Cursor to the beginning of the WorkingOps. void startFromBeginning(uint64_t &Loc, DIExpressionCursor &Cursor, ArrayRef<uint64_t> WorkingOps) { … } /// This function will canonicalize: /// 1. DW_OP_plus_uconst to DW_OP_constu <const-val> DW_OP_plus /// 2. DW_OP_lit<n> to DW_OP_constu <n> static SmallVector<uint64_t> canonicalizeDwarfOperations(ArrayRef<uint64_t> WorkingOps) { … } /// This function will convert: /// 1. DW_OP_constu <const-val> DW_OP_plus to DW_OP_plus_uconst /// 2. DW_OP_constu, 0 to DW_OP_lit0 static SmallVector<uint64_t> optimizeDwarfOperations(ArrayRef<uint64_t> WorkingOps) { … } /// {DW_OP_constu, 0, DW_OP_[plus, minus, shl, shr]} -> {} /// {DW_OP_constu, 1, DW_OP_[mul, div]} -> {} static bool tryFoldNoOpMath(uint64_t Const1, ArrayRef<DIExpression::ExprOperand> Ops, uint64_t &Loc, DIExpressionCursor &Cursor, SmallVectorImpl<uint64_t> &WorkingOps) { … } /// {DW_OP_constu, Const1, DW_OP_constu, Const2, DW_OP_[plus, /// minus, mul, div, shl, shr] -> {DW_OP_constu, Const1 [+, -, *, /, <<, >>] /// Const2} static bool tryFoldConstants(uint64_t Const1, ArrayRef<DIExpression::ExprOperand> Ops, uint64_t &Loc, DIExpressionCursor &Cursor, SmallVectorImpl<uint64_t> &WorkingOps) { … } /// {DW_OP_constu, Const1, DW_OP_[plus, mul], DW_OP_constu, Const2, /// DW_OP_[plus, mul]} -> {DW_OP_constu, Const1 [+, *] Const2, DW_OP_[plus, /// mul]} static bool tryFoldCommutativeMath(uint64_t Const1, ArrayRef<DIExpression::ExprOperand> Ops, uint64_t &Loc, DIExpressionCursor &Cursor, SmallVectorImpl<uint64_t> &WorkingOps) { … } /// {DW_OP_constu, Const1, DW_OP_[plus, mul], DW_OP_LLVM_arg, Arg1, /// DW_OP_[plus, mul], DW_OP_constu, Const2, DW_OP_[plus, mul]} -> /// {DW_OP_constu, Const1 [+, *] Const2, DW_OP_[plus, mul], DW_OP_LLVM_arg, /// Arg1, DW_OP_[plus, mul]} static bool tryFoldCommutativeMathWithArgInBetween( uint64_t Const1, ArrayRef<DIExpression::ExprOperand> Ops, uint64_t &Loc, DIExpressionCursor &Cursor, SmallVectorImpl<uint64_t> &WorkingOps) { … } DIExpression *DIExpression::foldConstantMath() { … }