10b57cec5SDimitry Andric //===-- llvm/CodeGen/PseudoSourceValue.cpp ----------------------*- 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 implements the PseudoSourceValue class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/CodeGen/PseudoSourceValue.h" 140b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 155f757f3fSDimitry Andric #include "llvm/CodeGen/PseudoSourceValueManager.h" 16*0fca6ea1SDimitry Andric #include "llvm/IR/GlobalValue.h" 170b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 180b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 1981ad6265SDimitry Andric #include "llvm/Target/TargetMachine.h" 2081ad6265SDimitry Andric 210b57cec5SDimitry Andric using namespace llvm; 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric static const char *const PSVNames[] = { 240b57cec5SDimitry Andric "Stack", "GOT", "JumpTable", "ConstantPool", "FixedStack", 250b57cec5SDimitry Andric "GlobalValueCallEntry", "ExternalSymbolCallEntry"}; 260b57cec5SDimitry Andric 2781ad6265SDimitry Andric PseudoSourceValue::PseudoSourceValue(unsigned Kind, const TargetMachine &TM) 280b57cec5SDimitry Andric : Kind(Kind) { 2981ad6265SDimitry Andric AddressSpace = TM.getAddressSpaceForPseudoSourceKind(Kind); 300b57cec5SDimitry Andric } 310b57cec5SDimitry Andric 3281ad6265SDimitry Andric PseudoSourceValue::~PseudoSourceValue() = default; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric void PseudoSourceValue::printCustom(raw_ostream &O) const { 350b57cec5SDimitry Andric if (Kind < TargetCustom) 360b57cec5SDimitry Andric O << PSVNames[Kind]; 370b57cec5SDimitry Andric else 380b57cec5SDimitry Andric O << "TargetCustom" << Kind; 390b57cec5SDimitry Andric } 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric bool PseudoSourceValue::isConstant(const MachineFrameInfo *) const { 420b57cec5SDimitry Andric if (isStack()) 430b57cec5SDimitry Andric return false; 440b57cec5SDimitry Andric if (isGOT() || isConstantPool() || isJumpTable()) 450b57cec5SDimitry Andric return true; 460b57cec5SDimitry Andric llvm_unreachable("Unknown PseudoSourceValue!"); 470b57cec5SDimitry Andric } 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric bool PseudoSourceValue::isAliased(const MachineFrameInfo *) const { 500b57cec5SDimitry Andric if (isStack() || isGOT() || isConstantPool() || isJumpTable()) 510b57cec5SDimitry Andric return false; 520b57cec5SDimitry Andric llvm_unreachable("Unknown PseudoSourceValue!"); 530b57cec5SDimitry Andric } 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric bool PseudoSourceValue::mayAlias(const MachineFrameInfo *) const { 560b57cec5SDimitry Andric return !(isGOT() || isConstantPool() || isJumpTable()); 570b57cec5SDimitry Andric } 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric bool FixedStackPseudoSourceValue::isConstant( 600b57cec5SDimitry Andric const MachineFrameInfo *MFI) const { 610b57cec5SDimitry Andric return MFI && MFI->isImmutableObjectIndex(FI); 620b57cec5SDimitry Andric } 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric bool FixedStackPseudoSourceValue::isAliased(const MachineFrameInfo *MFI) const { 650b57cec5SDimitry Andric if (!MFI) 660b57cec5SDimitry Andric return true; 670b57cec5SDimitry Andric return MFI->isAliasedObjectIndex(FI); 680b57cec5SDimitry Andric } 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric bool FixedStackPseudoSourceValue::mayAlias(const MachineFrameInfo *MFI) const { 710b57cec5SDimitry Andric if (!MFI) 720b57cec5SDimitry Andric return true; 730b57cec5SDimitry Andric // Spill slots will not alias any LLVM IR value. 740b57cec5SDimitry Andric return !MFI->isSpillSlotObjectIndex(FI); 750b57cec5SDimitry Andric } 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric void FixedStackPseudoSourceValue::printCustom(raw_ostream &OS) const { 780b57cec5SDimitry Andric OS << "FixedStack" << FI; 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric 8181ad6265SDimitry Andric CallEntryPseudoSourceValue::CallEntryPseudoSourceValue(unsigned Kind, 8281ad6265SDimitry Andric const TargetMachine &TM) 8381ad6265SDimitry Andric : PseudoSourceValue(Kind, TM) {} 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric bool CallEntryPseudoSourceValue::isConstant(const MachineFrameInfo *) const { 860b57cec5SDimitry Andric return false; 870b57cec5SDimitry Andric } 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric bool CallEntryPseudoSourceValue::isAliased(const MachineFrameInfo *) const { 900b57cec5SDimitry Andric return false; 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric bool CallEntryPseudoSourceValue::mayAlias(const MachineFrameInfo *) const { 940b57cec5SDimitry Andric return false; 950b57cec5SDimitry Andric } 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric GlobalValuePseudoSourceValue::GlobalValuePseudoSourceValue( 9881ad6265SDimitry Andric const GlobalValue *GV, const TargetMachine &TM) 9981ad6265SDimitry Andric : CallEntryPseudoSourceValue(GlobalValueCallEntry, TM), GV(GV) {} 1000b57cec5SDimitry Andric ExternalSymbolPseudoSourceValue::ExternalSymbolPseudoSourceValue( 10181ad6265SDimitry Andric const char *ES, const TargetMachine &TM) 10281ad6265SDimitry Andric : CallEntryPseudoSourceValue(ExternalSymbolCallEntry, TM), ES(ES) {} 1030b57cec5SDimitry Andric 10481ad6265SDimitry Andric PseudoSourceValueManager::PseudoSourceValueManager(const TargetMachine &TMInfo) 10581ad6265SDimitry Andric : TM(TMInfo), StackPSV(PseudoSourceValue::Stack, TM), 10681ad6265SDimitry Andric GOTPSV(PseudoSourceValue::GOT, TM), 10781ad6265SDimitry Andric JumpTablePSV(PseudoSourceValue::JumpTable, TM), 10881ad6265SDimitry Andric ConstantPoolPSV(PseudoSourceValue::ConstantPool, TM) {} 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric const PseudoSourceValue *PseudoSourceValueManager::getStack() { 1110b57cec5SDimitry Andric return &StackPSV; 1120b57cec5SDimitry Andric } 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric const PseudoSourceValue *PseudoSourceValueManager::getGOT() { return &GOTPSV; } 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric const PseudoSourceValue *PseudoSourceValueManager::getConstantPool() { 1170b57cec5SDimitry Andric return &ConstantPoolPSV; 1180b57cec5SDimitry Andric } 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric const PseudoSourceValue *PseudoSourceValueManager::getJumpTable() { 1210b57cec5SDimitry Andric return &JumpTablePSV; 1220b57cec5SDimitry Andric } 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric const PseudoSourceValue * 1250b57cec5SDimitry Andric PseudoSourceValueManager::getFixedStack(int FI) { 126*0fca6ea1SDimitry Andric // Frame index is often continuously positive, but can be negative. Use 127*0fca6ea1SDimitry Andric // zig-zag encoding for dense index into FSValues vector. 128*0fca6ea1SDimitry Andric unsigned Idx = (2 * unsigned(FI)) ^ (FI >> (sizeof(FI) * 8 - 1)); 129*0fca6ea1SDimitry Andric if (FSValues.size() <= Idx) 130*0fca6ea1SDimitry Andric FSValues.resize(Idx + 1); 131*0fca6ea1SDimitry Andric std::unique_ptr<FixedStackPseudoSourceValue> &V = FSValues[Idx]; 1320b57cec5SDimitry Andric if (!V) 13381ad6265SDimitry Andric V = std::make_unique<FixedStackPseudoSourceValue>(FI, TM); 1340b57cec5SDimitry Andric return V.get(); 1350b57cec5SDimitry Andric } 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric const PseudoSourceValue * 1380b57cec5SDimitry Andric PseudoSourceValueManager::getGlobalValueCallEntry(const GlobalValue *GV) { 1390b57cec5SDimitry Andric std::unique_ptr<const GlobalValuePseudoSourceValue> &E = 1400b57cec5SDimitry Andric GlobalCallEntries[GV]; 1410b57cec5SDimitry Andric if (!E) 14281ad6265SDimitry Andric E = std::make_unique<GlobalValuePseudoSourceValue>(GV, TM); 1430b57cec5SDimitry Andric return E.get(); 1440b57cec5SDimitry Andric } 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric const PseudoSourceValue * 1470b57cec5SDimitry Andric PseudoSourceValueManager::getExternalSymbolCallEntry(const char *ES) { 1480b57cec5SDimitry Andric std::unique_ptr<const ExternalSymbolPseudoSourceValue> &E = 1490b57cec5SDimitry Andric ExternalCallEntries[ES]; 1500b57cec5SDimitry Andric if (!E) 15181ad6265SDimitry Andric E = std::make_unique<ExternalSymbolPseudoSourceValue>(ES, TM); 1520b57cec5SDimitry Andric return E.get(); 1530b57cec5SDimitry Andric } 154