10b57cec5SDimitry Andric //===- CodeGen/Analysis.h - CodeGen LLVM IR Analysis Utilities --*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file declares several CodeGen-specific LLVM IR analysis utilities. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_CODEGEN_ANALYSIS_H 140b57cec5SDimitry Andric #define LLVM_CODEGEN_ANALYSIS_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 170b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/ISDOpcodes.h" 190b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace llvm { 2281ad6265SDimitry Andric template <typename T> class SmallVectorImpl; 230b57cec5SDimitry Andric class GlobalValue; 240b57cec5SDimitry Andric class LLT; 250b57cec5SDimitry Andric class MachineBasicBlock; 260b57cec5SDimitry Andric class MachineFunction; 270b57cec5SDimitry Andric class TargetLoweringBase; 280b57cec5SDimitry Andric class TargetLowering; 290b57cec5SDimitry Andric class TargetMachine; 300b57cec5SDimitry Andric struct EVT; 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric /// Compute the linearized index of a member in a nested 330b57cec5SDimitry Andric /// aggregate/struct/array. 340b57cec5SDimitry Andric /// 350b57cec5SDimitry Andric /// Given an LLVM IR aggregate type and a sequence of insertvalue or 360b57cec5SDimitry Andric /// extractvalue indices that identify a member, return the linearized index of 370b57cec5SDimitry Andric /// the start of the member, i.e the number of element in memory before the 380b57cec5SDimitry Andric /// sought one. This is disconnected from the number of bytes. 390b57cec5SDimitry Andric /// 400b57cec5SDimitry Andric /// \param Ty is the type indexed by \p Indices. 410b57cec5SDimitry Andric /// \param Indices is an optional pointer in the indices list to the current 420b57cec5SDimitry Andric /// index. 430b57cec5SDimitry Andric /// \param IndicesEnd is the end of the indices list. 440b57cec5SDimitry Andric /// \param CurIndex is the current index in the recursion. 450b57cec5SDimitry Andric /// 460b57cec5SDimitry Andric /// \returns \p CurIndex plus the linear index in \p Ty the indices list. 470b57cec5SDimitry Andric unsigned ComputeLinearIndex(Type *Ty, 480b57cec5SDimitry Andric const unsigned *Indices, 490b57cec5SDimitry Andric const unsigned *IndicesEnd, 500b57cec5SDimitry Andric unsigned CurIndex = 0); 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric inline unsigned ComputeLinearIndex(Type *Ty, 530b57cec5SDimitry Andric ArrayRef<unsigned> Indices, 540b57cec5SDimitry Andric unsigned CurIndex = 0) { 550b57cec5SDimitry Andric return ComputeLinearIndex(Ty, Indices.begin(), Indices.end(), CurIndex); 560b57cec5SDimitry Andric } 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric /// ComputeValueVTs - Given an LLVM IR type, compute a sequence of 590b57cec5SDimitry Andric /// EVTs that represent all the individual underlying 600b57cec5SDimitry Andric /// non-aggregate types that comprise it. 610b57cec5SDimitry Andric /// 620b57cec5SDimitry Andric /// If Offsets is non-null, it points to a vector to be filled in 630b57cec5SDimitry Andric /// with the in-memory offsets of each of the individual values. 640b57cec5SDimitry Andric /// 650b57cec5SDimitry Andric void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, 660b57cec5SDimitry Andric SmallVectorImpl<EVT> &ValueVTs, 6706c3fb27SDimitry Andric SmallVectorImpl<TypeSize> *Offsets, 6806c3fb27SDimitry Andric TypeSize StartingOffset); 6906c3fb27SDimitry Andric void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, 7006c3fb27SDimitry Andric SmallVectorImpl<EVT> &ValueVTs, 7106c3fb27SDimitry Andric SmallVectorImpl<TypeSize> *Offsets = nullptr, 720b57cec5SDimitry Andric uint64_t StartingOffset = 0); 7306c3fb27SDimitry Andric void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, 7406c3fb27SDimitry Andric SmallVectorImpl<EVT> &ValueVTs, 7506c3fb27SDimitry Andric SmallVectorImpl<uint64_t> *FixedOffsets, 7606c3fb27SDimitry Andric uint64_t StartingOffset); 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric /// Variant of ComputeValueVTs that also produces the memory VTs. 790b57cec5SDimitry Andric void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, 800b57cec5SDimitry Andric SmallVectorImpl<EVT> &ValueVTs, 810b57cec5SDimitry Andric SmallVectorImpl<EVT> *MemVTs, 8206c3fb27SDimitry Andric SmallVectorImpl<TypeSize> *Offsets, 8306c3fb27SDimitry Andric TypeSize StartingOffset); 8406c3fb27SDimitry Andric void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, 8506c3fb27SDimitry Andric SmallVectorImpl<EVT> &ValueVTs, 8606c3fb27SDimitry Andric SmallVectorImpl<EVT> *MemVTs, 8706c3fb27SDimitry Andric SmallVectorImpl<TypeSize> *Offsets = nullptr, 880b57cec5SDimitry Andric uint64_t StartingOffset = 0); 8906c3fb27SDimitry Andric void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, 9006c3fb27SDimitry Andric SmallVectorImpl<EVT> &ValueVTs, 9106c3fb27SDimitry Andric SmallVectorImpl<EVT> *MemVTs, 9206c3fb27SDimitry Andric SmallVectorImpl<uint64_t> *FixedOffsets, 9306c3fb27SDimitry Andric uint64_t StartingOffset); 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric /// computeValueLLTs - Given an LLVM IR type, compute a sequence of 960b57cec5SDimitry Andric /// LLTs that represent all the individual underlying 970b57cec5SDimitry Andric /// non-aggregate types that comprise it. 980b57cec5SDimitry Andric /// 990b57cec5SDimitry Andric /// If Offsets is non-null, it points to a vector to be filled in 1000b57cec5SDimitry Andric /// with the in-memory offsets of each of the individual values. 1010b57cec5SDimitry Andric /// 1020b57cec5SDimitry Andric void computeValueLLTs(const DataLayout &DL, Type &Ty, 1030b57cec5SDimitry Andric SmallVectorImpl<LLT> &ValueTys, 1040b57cec5SDimitry Andric SmallVectorImpl<uint64_t> *Offsets = nullptr, 1050b57cec5SDimitry Andric uint64_t StartingOffset = 0); 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric /// ExtractTypeInfo - Returns the type info, possibly bitcast, encoded in V. 1080b57cec5SDimitry Andric GlobalValue *ExtractTypeInfo(Value *V); 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric /// getFCmpCondCode - Return the ISD condition code corresponding to 1110b57cec5SDimitry Andric /// the given LLVM IR floating-point condition code. This includes 1120b57cec5SDimitry Andric /// consideration of global floating-point math flags. 1130b57cec5SDimitry Andric /// 1140b57cec5SDimitry Andric ISD::CondCode getFCmpCondCode(FCmpInst::Predicate Pred); 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric /// getFCmpCodeWithoutNaN - Given an ISD condition code comparing floats, 1170b57cec5SDimitry Andric /// return the equivalent code if we're allowed to assume that NaNs won't occur. 1180b57cec5SDimitry Andric ISD::CondCode getFCmpCodeWithoutNaN(ISD::CondCode CC); 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric /// getICmpCondCode - Return the ISD condition code corresponding to 1210b57cec5SDimitry Andric /// the given LLVM IR integer condition code. 1220b57cec5SDimitry Andric ISD::CondCode getICmpCondCode(ICmpInst::Predicate Pred); 1230b57cec5SDimitry Andric 124349cc55cSDimitry Andric /// getICmpCondCode - Return the LLVM IR integer condition code 125349cc55cSDimitry Andric /// corresponding to the given ISD integer condition code. 126349cc55cSDimitry Andric ICmpInst::Predicate getICmpCondCode(ISD::CondCode Pred); 127349cc55cSDimitry Andric 1280b57cec5SDimitry Andric /// Test if the given instruction is in a position to be optimized 1290b57cec5SDimitry Andric /// with a tail-call. This roughly means that it's in a block with 1300b57cec5SDimitry Andric /// a return and there's nothing that needs to be scheduled 1310b57cec5SDimitry Andric /// between it and the return. 1320b57cec5SDimitry Andric /// 1330b57cec5SDimitry Andric /// This function only tests target-independent requirements. 1345ffd83dbSDimitry Andric bool isInTailCallPosition(const CallBase &Call, const TargetMachine &TM); 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric /// Test if given that the input instruction is in the tail call position, if 1370b57cec5SDimitry Andric /// there is an attribute mismatch between the caller and the callee that will 1380b57cec5SDimitry Andric /// inhibit tail call optimizations. 1390b57cec5SDimitry Andric /// \p AllowDifferingSizes is an output parameter which, if forming a tail call 1400b57cec5SDimitry Andric /// is permitted, determines whether it's permitted only if the size of the 1410b57cec5SDimitry Andric /// caller's and callee's return types match exactly. 1420b57cec5SDimitry Andric bool attributesPermitTailCall(const Function *F, const Instruction *I, 1430b57cec5SDimitry Andric const ReturnInst *Ret, 1440b57cec5SDimitry Andric const TargetLoweringBase &TLI, 1450b57cec5SDimitry Andric bool *AllowDifferingSizes = nullptr); 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric /// Test if given that the input instruction is in the tail call position if the 1480b57cec5SDimitry Andric /// return type or any attributes of the function will inhibit tail call 1490b57cec5SDimitry Andric /// optimization. 1500b57cec5SDimitry Andric bool returnTypeIsEligibleForTailCall(const Function *F, const Instruction *I, 1510b57cec5SDimitry Andric const ReturnInst *Ret, 1520b57cec5SDimitry Andric const TargetLoweringBase &TLI); 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric DenseMap<const MachineBasicBlock *, int> 1550b57cec5SDimitry Andric getEHScopeMembership(const MachineFunction &MF); 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric } // End llvm namespace 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric #endif 160