1//===-- llvm/CodeGen/PseudoSourceValue.cpp ----------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the PseudoSourceValue class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/CodeGen/PseudoSourceValue.h"
15#include "llvm/CodeGen/MachineFrameInfo.h"
16#include "llvm/IR/DerivedTypes.h"
17#include "llvm/IR/LLVMContext.h"
18#include "llvm/Support/ErrorHandling.h"
19#include "llvm/Support/ManagedStatic.h"
20#include "llvm/Support/Mutex.h"
21#include "llvm/Support/raw_ostream.h"
22#include <map>
23using namespace llvm;
24
25namespace {
26struct PSVGlobalsTy {
27  // PseudoSourceValues are immutable so don't need locking.
28  const PseudoSourceValue PSVs[4];
29  sys::Mutex Lock;  // Guards FSValues, but not the values inside it.
30  std::map<int, const PseudoSourceValue *> FSValues;
31
32  PSVGlobalsTy() : PSVs() {}
33  ~PSVGlobalsTy() {
34    for (std::map<int, const PseudoSourceValue *>::iterator
35           I = FSValues.begin(), E = FSValues.end(); I != E; ++I) {
36      delete I->second;
37    }
38  }
39};
40
41static ManagedStatic<PSVGlobalsTy> PSVGlobals;
42
43}  // anonymous namespace
44
45const PseudoSourceValue *PseudoSourceValue::getStack()
46{ return &PSVGlobals->PSVs[0]; }
47const PseudoSourceValue *PseudoSourceValue::getGOT()
48{ return &PSVGlobals->PSVs[1]; }
49const PseudoSourceValue *PseudoSourceValue::getJumpTable()
50{ return &PSVGlobals->PSVs[2]; }
51const PseudoSourceValue *PseudoSourceValue::getConstantPool()
52{ return &PSVGlobals->PSVs[3]; }
53
54static const char *const PSVNames[] = {
55  "Stack",
56  "GOT",
57  "JumpTable",
58  "ConstantPool"
59};
60
61// FIXME: THIS IS A HACK!!!!
62// Eventually these should be uniqued on LLVMContext rather than in a managed
63// static.  For now, we can safely use the global context for the time being to
64// squeak by.
65PseudoSourceValue::PseudoSourceValue(enum ValueTy Subclass) :
66  Value(Type::getInt8PtrTy(getGlobalContext()),
67        Subclass) {}
68
69void PseudoSourceValue::printCustom(raw_ostream &O) const {
70  O << PSVNames[this - PSVGlobals->PSVs];
71}
72
73const PseudoSourceValue *PseudoSourceValue::getFixedStack(int FI) {
74  PSVGlobalsTy &PG = *PSVGlobals;
75  sys::ScopedLock locked(PG.Lock);
76  const PseudoSourceValue *&V = PG.FSValues[FI];
77  if (!V)
78    V = new FixedStackPseudoSourceValue(FI);
79  return V;
80}
81
82bool PseudoSourceValue::isConstant(const MachineFrameInfo *) const {
83  if (this == getStack())
84    return false;
85  if (this == getGOT() ||
86      this == getConstantPool() ||
87      this == getJumpTable())
88    return true;
89  llvm_unreachable("Unknown PseudoSourceValue!");
90}
91
92bool PseudoSourceValue::isAliased(const MachineFrameInfo *MFI) const {
93  if (this == getStack() ||
94      this == getGOT() ||
95      this == getConstantPool() ||
96      this == getJumpTable())
97    return false;
98  llvm_unreachable("Unknown PseudoSourceValue!");
99}
100
101bool PseudoSourceValue::mayAlias(const MachineFrameInfo *MFI) const {
102  if (this == getGOT() ||
103      this == getConstantPool() ||
104      this == getJumpTable())
105    return false;
106  return true;
107}
108
109bool FixedStackPseudoSourceValue::isConstant(const MachineFrameInfo *MFI) const{
110  return MFI && MFI->isImmutableObjectIndex(FI);
111}
112
113bool FixedStackPseudoSourceValue::isAliased(const MachineFrameInfo *MFI) const {
114  // Negative frame indices are used for special things that don't
115  // appear in LLVM IR. Non-negative indices may be used for things
116  // like static allocas.
117  if (!MFI)
118    return FI >= 0;
119  // Spill slots should not alias others.
120  return !MFI->isFixedObjectIndex(FI) && !MFI->isSpillSlotObjectIndex(FI);
121}
122
123bool FixedStackPseudoSourceValue::mayAlias(const MachineFrameInfo *MFI) const {
124  if (!MFI)
125    return true;
126  // Spill slots will not alias any LLVM IR value.
127  return !MFI->isSpillSlotObjectIndex(FI);
128}
129
130void FixedStackPseudoSourceValue::printCustom(raw_ostream &OS) const {
131  OS << "FixedStack" << FI;
132}
133