| //===-- llvm/CodeGen/PseudoSourceValue.cpp ----------------------*- C++ -*-===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // This file implements the PseudoSourceValue class. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "llvm/CodeGen/MachineFrameInfo.h" | |
| #include "llvm/CodeGen/PseudoSourceValue.h" | |
| #include "llvm/DerivedTypes.h" | |
| #include "llvm/LLVMContext.h" | |
| #include "llvm/Support/ErrorHandling.h" | |
| #include "llvm/Support/ManagedStatic.h" | |
| #include "llvm/Support/raw_ostream.h" | |
| #include "llvm/Support/Mutex.h" | |
| #include <map> | |
| using namespace llvm; | |
| namespace { | |
| struct PSVGlobalsTy { | |
| // PseudoSourceValues are immutable so don't need locking. | |
| const PseudoSourceValue PSVs[4]; | |
| sys::Mutex Lock; // Guards FSValues, but not the values inside it. | |
| std::map<int, const PseudoSourceValue *> FSValues; | |
| PSVGlobalsTy() : PSVs() {} | |
| ~PSVGlobalsTy() { | |
| for (std::map<int, const PseudoSourceValue *>::iterator | |
| I = FSValues.begin(), E = FSValues.end(); I != E; ++I) { | |
| delete I->second; | |
| } | |
| } | |
| }; | |
| static ManagedStatic<PSVGlobalsTy> PSVGlobals; | |
| } // anonymous namespace | |
| const PseudoSourceValue *PseudoSourceValue::getStack() | |
| { return &PSVGlobals->PSVs[0]; } | |
| const PseudoSourceValue *PseudoSourceValue::getGOT() | |
| { return &PSVGlobals->PSVs[1]; } | |
| const PseudoSourceValue *PseudoSourceValue::getJumpTable() | |
| { return &PSVGlobals->PSVs[2]; } | |
| const PseudoSourceValue *PseudoSourceValue::getConstantPool() | |
| { return &PSVGlobals->PSVs[3]; } | |
| static const char *const PSVNames[] = { | |
| "Stack", | |
| "GOT", | |
| "JumpTable", | |
| "ConstantPool" | |
| }; | |
| // FIXME: THIS IS A HACK!!!! | |
| // Eventually these should be uniqued on LLVMContext rather than in a managed | |
| // static. For now, we can safely use the global context for the time being to | |
| // squeak by. | |
| PseudoSourceValue::PseudoSourceValue(enum ValueTy Subclass) : | |
| Value(Type::getInt8PtrTy(getGlobalContext()), | |
| Subclass) {} | |
| void PseudoSourceValue::printCustom(raw_ostream &O) const { | |
| O << PSVNames[this - PSVGlobals->PSVs]; | |
| } | |
| const PseudoSourceValue *PseudoSourceValue::getFixedStack(int FI) { | |
| PSVGlobalsTy &PG = *PSVGlobals; | |
| sys::ScopedLock locked(PG.Lock); | |
| const PseudoSourceValue *&V = PG.FSValues[FI]; | |
| if (!V) | |
| V = new FixedStackPseudoSourceValue(FI); | |
| return V; | |
| } | |
| bool PseudoSourceValue::isConstant(const MachineFrameInfo *) const { | |
| if (this == getStack()) | |
| return false; | |
| if (this == getGOT() || | |
| this == getConstantPool() || | |
| this == getJumpTable()) | |
| return true; | |
| llvm_unreachable("Unknown PseudoSourceValue!"); | |
| return false; | |
| } | |
| bool PseudoSourceValue::isAliased(const MachineFrameInfo *MFI) const { | |
| if (this == getStack() || | |
| this == getGOT() || | |
| this == getConstantPool() || | |
| this == getJumpTable()) | |
| return false; | |
| llvm_unreachable("Unknown PseudoSourceValue!"); | |
| return true; | |
| } | |
| bool PseudoSourceValue::mayAlias(const MachineFrameInfo *MFI) const { | |
| if (this == getGOT() || | |
| this == getConstantPool() || | |
| this == getJumpTable()) | |
| return false; | |
| return true; | |
| } | |
| bool FixedStackPseudoSourceValue::isConstant(const MachineFrameInfo *MFI) const{ | |
| return MFI && MFI->isImmutableObjectIndex(FI); | |
| } | |
| bool FixedStackPseudoSourceValue::isAliased(const MachineFrameInfo *MFI) const { | |
| // Negative frame indices are used for special things that don't | |
| // appear in LLVM IR. Non-negative indices may be used for things | |
| // like static allocas. | |
| if (!MFI) | |
| return FI >= 0; | |
| // Spill slots should not alias others. | |
| return !MFI->isFixedObjectIndex(FI) && !MFI->isSpillSlotObjectIndex(FI); | |
| } | |
| bool FixedStackPseudoSourceValue::mayAlias(const MachineFrameInfo *MFI) const { | |
| if (!MFI) | |
| return true; | |
| // Spill slots will not alias any LLVM IR value. | |
| return !MFI->isSpillSlotObjectIndex(FI); | |
| } | |
| void FixedStackPseudoSourceValue::printCustom(raw_ostream &OS) const { | |
| OS << "FixedStack" << FI; | |
| } |