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