|
|
|||
File indexing completed on 2026-05-10 08:43:23
0001 //===-- llvm/CodeGen/GlobalISel/CSEMIRBuilder.h --*- C++ -*-==// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 /// \file 0009 /// This file implements a version of MachineIRBuilder which CSEs insts within 0010 /// a MachineBasicBlock. 0011 //===----------------------------------------------------------------------===// 0012 #ifndef LLVM_CODEGEN_GLOBALISEL_CSEMIRBUILDER_H 0013 #define LLVM_CODEGEN_GLOBALISEL_CSEMIRBUILDER_H 0014 0015 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 0016 0017 namespace llvm { 0018 0019 class GISelInstProfileBuilder; 0020 /// Defines a builder that does CSE of MachineInstructions using GISelCSEInfo. 0021 /// Eg usage. 0022 /// 0023 /// \code 0024 /// GISelCSEInfo *Info = 0025 /// &getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEInfo(); 0026 /// CSEMIRBuilder CB(Builder.getState()); 0027 /// CB.setCSEInfo(Info); 0028 /// auto A = CB.buildConstant(s32, 42); 0029 /// auto B = CB.buildConstant(s32, 42); 0030 /// assert(A == B); 0031 /// unsigned CReg = MRI.createGenericVirtualRegister(s32); 0032 /// auto C = CB.buildConstant(CReg, 42); 0033 /// assert(C->getOpcode() == TargetOpcode::COPY); 0034 /// \endcode 0035 /// 0036 /// Explicitly passing in a register would materialize a copy if possible. 0037 /// CSEMIRBuilder also does trivial constant folding for binary ops. 0038 class CSEMIRBuilder : public MachineIRBuilder { 0039 0040 /// Returns true if A dominates B (within the same basic block). 0041 /// Both iterators must be in the same basic block. 0042 // 0043 // TODO: Another approach for checking dominance is having two iterators and 0044 // making them go towards each other until they meet or reach begin/end. Which 0045 // approach is better? Should this even change dynamically? For G_CONSTANTS 0046 // most of which will be at the top of the BB, the top down approach would be 0047 // a better choice. Does IRTranslator placing constants at the beginning still 0048 // make sense? Should this change based on Opcode? 0049 bool dominates(MachineBasicBlock::const_iterator A, 0050 MachineBasicBlock::const_iterator B) const; 0051 0052 /// For given ID, find a machineinstr in the CSE Map. If found, check if it 0053 /// dominates the current insertion point and if not, move it just before the 0054 /// current insertion point and return it. If not found, return Null 0055 /// MachineInstrBuilder. 0056 MachineInstrBuilder getDominatingInstrForID(FoldingSetNodeID &ID, 0057 void *&NodeInsertPos); 0058 /// Simple check if we can CSE (we have the CSEInfo) or if this Opcode is 0059 /// safe to CSE. 0060 bool canPerformCSEForOpc(unsigned Opc) const; 0061 0062 void profileDstOp(const DstOp &Op, GISelInstProfileBuilder &B) const; 0063 0064 void profileDstOps(ArrayRef<DstOp> Ops, GISelInstProfileBuilder &B) const { 0065 for (const DstOp &Op : Ops) 0066 profileDstOp(Op, B); 0067 } 0068 0069 void profileSrcOp(const SrcOp &Op, GISelInstProfileBuilder &B) const; 0070 0071 void profileSrcOps(ArrayRef<SrcOp> Ops, GISelInstProfileBuilder &B) const { 0072 for (const SrcOp &Op : Ops) 0073 profileSrcOp(Op, B); 0074 } 0075 0076 void profileMBBOpcode(GISelInstProfileBuilder &B, unsigned Opc) const; 0077 0078 void profileEverything(unsigned Opc, ArrayRef<DstOp> DstOps, 0079 ArrayRef<SrcOp> SrcOps, std::optional<unsigned> Flags, 0080 GISelInstProfileBuilder &B) const; 0081 0082 // Takes a MachineInstrBuilder and inserts it into the CSEMap using the 0083 // NodeInsertPos. 0084 MachineInstrBuilder memoizeMI(MachineInstrBuilder MIB, void *NodeInsertPos); 0085 0086 // If we have can CSE an instruction, but still need to materialize to a VReg, 0087 // we emit a copy from the CSE'd inst to the VReg. 0088 MachineInstrBuilder generateCopiesIfRequired(ArrayRef<DstOp> DstOps, 0089 MachineInstrBuilder &MIB); 0090 0091 // If we have can CSE an instruction, but still need to materialize to a VReg, 0092 // check if we can generate copies. It's not possible to return a single MIB, 0093 // while emitting copies to multiple vregs. 0094 bool checkCopyToDefsPossible(ArrayRef<DstOp> DstOps); 0095 0096 public: 0097 // Pull in base class constructors. 0098 using MachineIRBuilder::MachineIRBuilder; 0099 // Unhide buildInstr 0100 MachineInstrBuilder 0101 buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps, ArrayRef<SrcOp> SrcOps, 0102 std::optional<unsigned> Flag = std::nullopt) override; 0103 // Bring in the other overload from the base class. 0104 using MachineIRBuilder::buildConstant; 0105 0106 MachineInstrBuilder buildConstant(const DstOp &Res, 0107 const ConstantInt &Val) override; 0108 0109 // Bring in the other overload from the base class. 0110 using MachineIRBuilder::buildFConstant; 0111 MachineInstrBuilder buildFConstant(const DstOp &Res, 0112 const ConstantFP &Val) override; 0113 }; 0114 } // namespace llvm 0115 #endif
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|