Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===-- llvm/CodeGen/GlobalISel/CSEMIRBuilder.h  --*- C++ -*-==//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. /// \file
  9. /// This file implements a version of MachineIRBuilder which CSEs insts within
  10. /// a MachineBasicBlock.
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LLVM_CODEGEN_GLOBALISEL_CSEMIRBUILDER_H
  13. #define LLVM_CODEGEN_GLOBALISEL_CSEMIRBUILDER_H
  14.  
  15. #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
  16.  
  17. namespace llvm {
  18.  
  19. class GISelInstProfileBuilder;
  20. /// Defines a builder that does CSE of MachineInstructions using GISelCSEInfo.
  21. /// Eg usage.
  22. ///
  23. ///
  24. /// GISelCSEInfo *Info =
  25. /// &getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEInfo(); CSEMIRBuilder
  26. /// CB(Builder.getState()); CB.setCSEInfo(Info); auto A = CB.buildConstant(s32,
  27. /// 42); auto B = CB.buildConstant(s32, 42); assert(A == B); unsigned CReg =
  28. /// MRI.createGenericVirtualRegister(s32); auto C = CB.buildConstant(CReg, 42);
  29. /// assert(C->getOpcode() == TargetOpcode::COPY);
  30. /// Explicitly passing in a register would materialize a copy if possible.
  31. /// CSEMIRBuilder also does trivial constant folding for binary ops.
  32. class CSEMIRBuilder : public MachineIRBuilder {
  33.  
  34.   /// Returns true if A dominates B (within the same basic block).
  35.   /// Both iterators must be in the same basic block.
  36.   //
  37.   // TODO: Another approach for checking dominance is having two iterators and
  38.   // making them go towards each other until they meet or reach begin/end. Which
  39.   // approach is better? Should this even change dynamically? For G_CONSTANTS
  40.   // most of which will be at the top of the BB, the top down approach would be
  41.   // a better choice. Does IRTranslator placing constants at the beginning still
  42.   // make sense? Should this change based on Opcode?
  43.   bool dominates(MachineBasicBlock::const_iterator A,
  44.                  MachineBasicBlock::const_iterator B) const;
  45.  
  46.   /// For given ID, find a machineinstr in the CSE Map. If found, check if it
  47.   /// dominates the current insertion point and if not, move it just before the
  48.   /// current insertion point and return it. If not found, return Null
  49.   /// MachineInstrBuilder.
  50.   MachineInstrBuilder getDominatingInstrForID(FoldingSetNodeID &ID,
  51.                                               void *&NodeInsertPos);
  52.   /// Simple check if we can CSE (we have the CSEInfo) or if this Opcode is
  53.   /// safe to CSE.
  54.   bool canPerformCSEForOpc(unsigned Opc) const;
  55.  
  56.   void profileDstOp(const DstOp &Op, GISelInstProfileBuilder &B) const;
  57.  
  58.   void profileDstOps(ArrayRef<DstOp> Ops, GISelInstProfileBuilder &B) const {
  59.     for (const DstOp &Op : Ops)
  60.       profileDstOp(Op, B);
  61.   }
  62.  
  63.   void profileSrcOp(const SrcOp &Op, GISelInstProfileBuilder &B) const;
  64.  
  65.   void profileSrcOps(ArrayRef<SrcOp> Ops, GISelInstProfileBuilder &B) const {
  66.     for (const SrcOp &Op : Ops)
  67.       profileSrcOp(Op, B);
  68.   }
  69.  
  70.   void profileMBBOpcode(GISelInstProfileBuilder &B, unsigned Opc) const;
  71.  
  72.   void profileEverything(unsigned Opc, ArrayRef<DstOp> DstOps,
  73.                          ArrayRef<SrcOp> SrcOps, std::optional<unsigned> Flags,
  74.                          GISelInstProfileBuilder &B) const;
  75.  
  76.   // Takes a MachineInstrBuilder and inserts it into the CSEMap using the
  77.   // NodeInsertPos.
  78.   MachineInstrBuilder memoizeMI(MachineInstrBuilder MIB, void *NodeInsertPos);
  79.  
  80.   // If we have can CSE an instruction, but still need to materialize to a VReg,
  81.   // we emit a copy from the CSE'd inst to the VReg.
  82.   MachineInstrBuilder generateCopiesIfRequired(ArrayRef<DstOp> DstOps,
  83.                                                MachineInstrBuilder &MIB);
  84.  
  85.   // If we have can CSE an instruction, but still need to materialize to a VReg,
  86.   // check if we can generate copies. It's not possible to return a single MIB,
  87.   // while emitting copies to multiple vregs.
  88.   bool checkCopyToDefsPossible(ArrayRef<DstOp> DstOps);
  89.  
  90. public:
  91.   // Pull in base class constructors.
  92.   using MachineIRBuilder::MachineIRBuilder;
  93.   // Unhide buildInstr
  94.   MachineInstrBuilder
  95.   buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps, ArrayRef<SrcOp> SrcOps,
  96.              std::optional<unsigned> Flag = std::nullopt) override;
  97.   // Bring in the other overload from the base class.
  98.   using MachineIRBuilder::buildConstant;
  99.  
  100.   MachineInstrBuilder buildConstant(const DstOp &Res,
  101.                                     const ConstantInt &Val) override;
  102.  
  103.   // Bring in the other overload from the base class.
  104.   using MachineIRBuilder::buildFConstant;
  105.   MachineInstrBuilder buildFConstant(const DstOp &Res,
  106.                                      const ConstantFP &Val) override;
  107. };
  108. } // namespace llvm
  109. #endif
  110.