diff options
Diffstat (limited to 'lib/Target/Mips/MipsRegisterBankInfo.h')
| -rw-r--r-- | lib/Target/Mips/MipsRegisterBankInfo.h | 132 |
1 files changed, 128 insertions, 4 deletions
diff --git a/lib/Target/Mips/MipsRegisterBankInfo.h b/lib/Target/Mips/MipsRegisterBankInfo.h index 64a79abaa74d..176813c031ed 100644 --- a/lib/Target/Mips/MipsRegisterBankInfo.h +++ b/lib/Target/Mips/MipsRegisterBankInfo.h @@ -1,9 +1,8 @@ //===- MipsRegisterBankInfo.h -----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// \file @@ -38,6 +37,131 @@ public: const InstructionMapping & getInstrMapping(const MachineInstr &MI) const override; + + void applyMappingImpl(const OperandsMapper &OpdMapper) const override; + +private: + /// Some instructions are used with both floating point and integer operands. + /// We assign InstType to such instructions as it helps us to avoid cross bank + /// copies. InstType deppends on context. + enum InstType { + /// Temporary type, when visit(..., nullptr) finishes will convert to one of + /// the remaining types: Integer, FloatingPoint or Ambiguous. + NotDetermined, + /// Connected with instruction that interprets 'bags of bits' as integers. + /// Select gprb to avoid cross bank copies. + Integer, + /// Connected with instruction that interprets 'bags of bits' as floating + /// point numbers. Select fprb to avoid cross bank copies. + FloatingPoint, + /// Represents moving 'bags of bits' around. Select same bank for entire + /// chain to avoid cross bank copies. Currently we select fprb for s64 and + /// gprb for s32 Ambiguous operands. + Ambiguous + }; + + /// Some generic instructions have operands that can be mapped to either fprb + /// or gprb e.g. for G_LOAD we consider only operand 0 as ambiguous, operand 1 + /// is always gprb since it is a pointer. + /// This class provides containers for MI's ambiguous: + /// DefUses : MachineInstrs that use one of MI's ambiguous def operands. + /// UseDefs : MachineInstrs that define MI's ambiguous use operands. + class AmbiguousRegDefUseContainer { + SmallVector<MachineInstr *, 2> DefUses; + SmallVector<MachineInstr *, 2> UseDefs; + + void addDefUses(Register Reg, const MachineRegisterInfo &MRI); + void addUseDef(Register Reg, const MachineRegisterInfo &MRI); + + /// Skip copy instructions until we get to a non-copy instruction or to a + /// copy with phys register as def. Used during search for DefUses. + /// MI : %5 = COPY %4 + /// %6 = COPY %5 + /// $v0 = COPY %6 <- we want this one. + MachineInstr *skipCopiesOutgoing(MachineInstr *MI) const; + + /// Skip copy instructions until we get to a non-copy instruction or to a + /// copy with phys register as use. Used during search for UseDefs. + /// %1 = COPY $a1 <- we want this one. + /// %2 = COPY %1 + /// MI = %3 = COPY %2 + MachineInstr *skipCopiesIncoming(MachineInstr *MI) const; + + public: + AmbiguousRegDefUseContainer(const MachineInstr *MI); + SmallVectorImpl<MachineInstr *> &getDefUses() { return DefUses; } + SmallVectorImpl<MachineInstr *> &getUseDefs() { return UseDefs; } + }; + + class TypeInfoForMF { + /// MachineFunction name is used to recognise when MF changes. + std::string MFName = ""; + /// <key, value> : value is vector of all MachineInstrs that are waiting for + /// key to figure out type of some of its ambiguous operands. + DenseMap<const MachineInstr *, SmallVector<const MachineInstr *, 2>> + WaitingQueues; + /// Recorded InstTypes for visited instructions. + DenseMap<const MachineInstr *, InstType> Types; + + /// Recursively visit MI's adjacent instructions and find MI's InstType. + bool visit(const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI); + + /// Visit MI's adjacent UseDefs or DefUses. + bool visitAdjacentInstrs(const MachineInstr *MI, + SmallVectorImpl<MachineInstr *> &AdjacentInstrs, + bool isDefUse); + + /// Set type for MI, and recursively for all instructions that are + /// waiting for MI's type. + void setTypes(const MachineInstr *MI, InstType ITy); + + /// InstType for MI is determined, set it to InstType that corresponds to + /// physical regisiter that is operand number Op in CopyInst. + void setTypesAccordingToPhysicalRegister(const MachineInstr *MI, + const MachineInstr *CopyInst, + unsigned Op); + + /// Set default values for MI in order to start visit. + void startVisit(const MachineInstr *MI) { + Types.try_emplace(MI, InstType::NotDetermined); + WaitingQueues.try_emplace(MI); + } + + /// Returns true if instruction was already visited. Type might not be + /// determined at this point but will be when visit(..., nullptr) finishes. + bool wasVisited(const MachineInstr *MI) const { return Types.count(MI); }; + + /// Returns recorded type for instruction. + const InstType &getRecordedTypeForInstr(const MachineInstr *MI) const { + assert(wasVisited(MI) && "Instruction was not visited!"); + return Types.find(MI)->getSecond(); + }; + + /// Change recorded type for instruction. + void changeRecordedTypeForInstr(const MachineInstr *MI, InstType InstTy) { + assert(wasVisited(MI) && "Instruction was not visited!"); + Types.find(MI)->getSecond() = InstTy; + }; + + /// Returns WaitingQueue for instruction. + const SmallVectorImpl<const MachineInstr *> & + getWaitingQueueFor(const MachineInstr *MI) const { + assert(WaitingQueues.count(MI) && "Instruction was not visited!"); + return WaitingQueues.find(MI)->getSecond(); + }; + + /// Add WaitingForMI to MI's WaitingQueue. + void addToWaitingQueue(const MachineInstr *MI, + const MachineInstr *WaitingForMI) { + assert(WaitingQueues.count(MI) && "Instruction was not visited!"); + WaitingQueues.find(MI)->getSecond().push_back(WaitingForMI); + }; + + public: + InstType determineInstType(const MachineInstr *MI); + + void cleanupIfNewFunction(llvm::StringRef FunctionName); + }; }; } // end namespace llvm #endif |
