xref: /src/contrib/llvm-project/llvm/lib/CodeGen/PseudoSourceValue.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1009b1c42SEd Schouten //===-- llvm/CodeGen/PseudoSourceValue.cpp ----------------------*- C++ -*-===//
2009b1c42SEd Schouten //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6009b1c42SEd Schouten //
7009b1c42SEd Schouten //===----------------------------------------------------------------------===//
8009b1c42SEd Schouten //
9009b1c42SEd Schouten // This file implements the PseudoSourceValue class.
10009b1c42SEd Schouten //
11009b1c42SEd Schouten //===----------------------------------------------------------------------===//
12009b1c42SEd Schouten 
13009b1c42SEd Schouten #include "llvm/CodeGen/PseudoSourceValue.h"
144a16efa3SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
15b1c73532SDimitry Andric #include "llvm/CodeGen/PseudoSourceValueManager.h"
16ac9a064cSDimitry Andric #include "llvm/IR/GlobalValue.h"
1759850d08SRoman Divacky #include "llvm/Support/ErrorHandling.h"
184a16efa3SDimitry Andric #include "llvm/Support/raw_ostream.h"
19145449b1SDimitry Andric #include "llvm/Target/TargetMachine.h"
20145449b1SDimitry Andric 
21009b1c42SEd Schouten using namespace llvm;
22009b1c42SEd Schouten 
23009b1c42SEd Schouten static const char *const PSVNames[] = {
24dd58ef01SDimitry Andric     "Stack", "GOT", "JumpTable", "ConstantPool", "FixedStack",
25dd58ef01SDimitry Andric     "GlobalValueCallEntry", "ExternalSymbolCallEntry"};
26009b1c42SEd Schouten 
PseudoSourceValue(unsigned Kind,const TargetMachine & TM)27145449b1SDimitry Andric PseudoSourceValue::PseudoSourceValue(unsigned Kind, const TargetMachine &TM)
28044eb2f6SDimitry Andric     : Kind(Kind) {
29145449b1SDimitry Andric   AddressSpace = TM.getAddressSpaceForPseudoSourceKind(Kind);
30044eb2f6SDimitry Andric }
31044eb2f6SDimitry Andric 
32145449b1SDimitry Andric PseudoSourceValue::~PseudoSourceValue() = default;
33009b1c42SEd Schouten 
printCustom(raw_ostream & O) const3459850d08SRoman Divacky void PseudoSourceValue::printCustom(raw_ostream &O) const {
3571d5a254SDimitry Andric   if (Kind < TargetCustom)
36dd58ef01SDimitry Andric     O << PSVNames[Kind];
3771d5a254SDimitry Andric   else
3871d5a254SDimitry Andric     O << "TargetCustom" << Kind;
39009b1c42SEd Schouten }
40009b1c42SEd Schouten 
isConstant(const MachineFrameInfo *) const41009b1c42SEd Schouten bool PseudoSourceValue::isConstant(const MachineFrameInfo *) const {
42dd58ef01SDimitry Andric   if (isStack())
43009b1c42SEd Schouten     return false;
44dd58ef01SDimitry Andric   if (isGOT() || isConstantPool() || isJumpTable())
45009b1c42SEd Schouten     return true;
4659850d08SRoman Divacky   llvm_unreachable("Unknown PseudoSourceValue!");
47009b1c42SEd Schouten }
48009b1c42SEd Schouten 
isAliased(const MachineFrameInfo *) const49dd58ef01SDimitry Andric bool PseudoSourceValue::isAliased(const MachineFrameInfo *) const {
50dd58ef01SDimitry Andric   if (isStack() || isGOT() || isConstantPool() || isJumpTable())
514a142eb2SRoman Divacky     return false;
524a142eb2SRoman Divacky   llvm_unreachable("Unknown PseudoSourceValue!");
534a142eb2SRoman Divacky }
544a142eb2SRoman Divacky 
mayAlias(const MachineFrameInfo *) const55dd58ef01SDimitry Andric bool PseudoSourceValue::mayAlias(const MachineFrameInfo *) const {
56dd58ef01SDimitry Andric   return !(isGOT() || isConstantPool() || isJumpTable());
5736bf506aSRoman Divacky }
5836bf506aSRoman Divacky 
isConstant(const MachineFrameInfo * MFI) const59dd58ef01SDimitry Andric bool FixedStackPseudoSourceValue::isConstant(
60dd58ef01SDimitry Andric     const MachineFrameInfo *MFI) const {
61009b1c42SEd Schouten   return MFI && MFI->isImmutableObjectIndex(FI);
62009b1c42SEd Schouten }
634a142eb2SRoman Divacky 
isAliased(const MachineFrameInfo * MFI) const644a142eb2SRoman Divacky bool FixedStackPseudoSourceValue::isAliased(const MachineFrameInfo *MFI) const {
654a142eb2SRoman Divacky   if (!MFI)
6667c32a98SDimitry Andric     return true;
6767c32a98SDimitry Andric   return MFI->isAliasedObjectIndex(FI);
684a142eb2SRoman Divacky }
6936bf506aSRoman Divacky 
mayAlias(const MachineFrameInfo * MFI) const7036bf506aSRoman Divacky bool FixedStackPseudoSourceValue::mayAlias(const MachineFrameInfo *MFI) const {
7136bf506aSRoman Divacky   if (!MFI)
7236bf506aSRoman Divacky     return true;
7336bf506aSRoman Divacky   // Spill slots will not alias any LLVM IR value.
7436bf506aSRoman Divacky   return !MFI->isSpillSlotObjectIndex(FI);
7536bf506aSRoman Divacky }
76907da171SRoman Divacky 
printCustom(raw_ostream & OS) const77907da171SRoman Divacky void FixedStackPseudoSourceValue::printCustom(raw_ostream &OS) const {
78907da171SRoman Divacky   OS << "FixedStack" << FI;
79907da171SRoman Divacky }
80dd58ef01SDimitry Andric 
CallEntryPseudoSourceValue(unsigned Kind,const TargetMachine & TM)81145449b1SDimitry Andric CallEntryPseudoSourceValue::CallEntryPseudoSourceValue(unsigned Kind,
82145449b1SDimitry Andric                                                        const TargetMachine &TM)
83145449b1SDimitry Andric     : PseudoSourceValue(Kind, TM) {}
84dd58ef01SDimitry Andric 
isConstant(const MachineFrameInfo *) const85dd58ef01SDimitry Andric bool CallEntryPseudoSourceValue::isConstant(const MachineFrameInfo *) const {
86dd58ef01SDimitry Andric   return false;
87dd58ef01SDimitry Andric }
88dd58ef01SDimitry Andric 
isAliased(const MachineFrameInfo *) const89dd58ef01SDimitry Andric bool CallEntryPseudoSourceValue::isAliased(const MachineFrameInfo *) const {
90dd58ef01SDimitry Andric   return false;
91dd58ef01SDimitry Andric }
92dd58ef01SDimitry Andric 
mayAlias(const MachineFrameInfo *) const93dd58ef01SDimitry Andric bool CallEntryPseudoSourceValue::mayAlias(const MachineFrameInfo *) const {
94dd58ef01SDimitry Andric   return false;
95dd58ef01SDimitry Andric }
96dd58ef01SDimitry Andric 
GlobalValuePseudoSourceValue(const GlobalValue * GV,const TargetMachine & TM)97dd58ef01SDimitry Andric GlobalValuePseudoSourceValue::GlobalValuePseudoSourceValue(
98145449b1SDimitry Andric     const GlobalValue *GV, const TargetMachine &TM)
99145449b1SDimitry Andric     : CallEntryPseudoSourceValue(GlobalValueCallEntry, TM), GV(GV) {}
ExternalSymbolPseudoSourceValue(const char * ES,const TargetMachine & TM)100044eb2f6SDimitry Andric ExternalSymbolPseudoSourceValue::ExternalSymbolPseudoSourceValue(
101145449b1SDimitry Andric     const char *ES, const TargetMachine &TM)
102145449b1SDimitry Andric     : CallEntryPseudoSourceValue(ExternalSymbolCallEntry, TM), ES(ES) {}
103dd58ef01SDimitry Andric 
PseudoSourceValueManager(const TargetMachine & TMInfo)104145449b1SDimitry Andric PseudoSourceValueManager::PseudoSourceValueManager(const TargetMachine &TMInfo)
105145449b1SDimitry Andric     : TM(TMInfo), StackPSV(PseudoSourceValue::Stack, TM),
106145449b1SDimitry Andric       GOTPSV(PseudoSourceValue::GOT, TM),
107145449b1SDimitry Andric       JumpTablePSV(PseudoSourceValue::JumpTable, TM),
108145449b1SDimitry Andric       ConstantPoolPSV(PseudoSourceValue::ConstantPool, TM) {}
109dd58ef01SDimitry Andric 
getStack()110dd58ef01SDimitry Andric const PseudoSourceValue *PseudoSourceValueManager::getStack() {
111dd58ef01SDimitry Andric   return &StackPSV;
112dd58ef01SDimitry Andric }
113dd58ef01SDimitry Andric 
getGOT()114dd58ef01SDimitry Andric const PseudoSourceValue *PseudoSourceValueManager::getGOT() { return &GOTPSV; }
115dd58ef01SDimitry Andric 
getConstantPool()116dd58ef01SDimitry Andric const PseudoSourceValue *PseudoSourceValueManager::getConstantPool() {
117dd58ef01SDimitry Andric   return &ConstantPoolPSV;
118dd58ef01SDimitry Andric }
119dd58ef01SDimitry Andric 
getJumpTable()120dd58ef01SDimitry Andric const PseudoSourceValue *PseudoSourceValueManager::getJumpTable() {
121dd58ef01SDimitry Andric   return &JumpTablePSV;
122dd58ef01SDimitry Andric }
123dd58ef01SDimitry Andric 
124044eb2f6SDimitry Andric const PseudoSourceValue *
getFixedStack(int FI)125044eb2f6SDimitry Andric PseudoSourceValueManager::getFixedStack(int FI) {
126ac9a064cSDimitry Andric   // Frame index is often continuously positive, but can be negative. Use
127ac9a064cSDimitry Andric   // zig-zag encoding for dense index into FSValues vector.
128ac9a064cSDimitry Andric   unsigned Idx = (2 * unsigned(FI)) ^ (FI >> (sizeof(FI) * 8 - 1));
129ac9a064cSDimitry Andric   if (FSValues.size() <= Idx)
130ac9a064cSDimitry Andric     FSValues.resize(Idx + 1);
131ac9a064cSDimitry Andric   std::unique_ptr<FixedStackPseudoSourceValue> &V = FSValues[Idx];
132dd58ef01SDimitry Andric   if (!V)
133145449b1SDimitry Andric     V = std::make_unique<FixedStackPseudoSourceValue>(FI, TM);
134dd58ef01SDimitry Andric   return V.get();
135dd58ef01SDimitry Andric }
136dd58ef01SDimitry Andric 
137dd58ef01SDimitry Andric const PseudoSourceValue *
getGlobalValueCallEntry(const GlobalValue * GV)138dd58ef01SDimitry Andric PseudoSourceValueManager::getGlobalValueCallEntry(const GlobalValue *GV) {
139dd58ef01SDimitry Andric   std::unique_ptr<const GlobalValuePseudoSourceValue> &E =
140dd58ef01SDimitry Andric       GlobalCallEntries[GV];
141dd58ef01SDimitry Andric   if (!E)
142145449b1SDimitry Andric     E = std::make_unique<GlobalValuePseudoSourceValue>(GV, TM);
143dd58ef01SDimitry Andric   return E.get();
144dd58ef01SDimitry Andric }
145dd58ef01SDimitry Andric 
146dd58ef01SDimitry Andric const PseudoSourceValue *
getExternalSymbolCallEntry(const char * ES)147dd58ef01SDimitry Andric PseudoSourceValueManager::getExternalSymbolCallEntry(const char *ES) {
148dd58ef01SDimitry Andric   std::unique_ptr<const ExternalSymbolPseudoSourceValue> &E =
149dd58ef01SDimitry Andric       ExternalCallEntries[ES];
150dd58ef01SDimitry Andric   if (!E)
151145449b1SDimitry Andric     E = std::make_unique<ExternalSymbolPseudoSourceValue>(ES, TM);
152dd58ef01SDimitry Andric   return E.get();
153dd58ef01SDimitry Andric }
154