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/MachineFrameInfo.h"
15#include "llvm/CodeGen/PseudoSourceValue.h"
16#include "llvm/DerivedTypes.h"
17#include "llvm/LLVMContext.h"
18#include "llvm/Support/ErrorHandling.h"
19#include "llvm/Support/ManagedStatic.h"
20#include "llvm/Support/raw_ostream.h"
21#include "llvm/Support/Mutex.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  return false;
91}
92
93bool PseudoSourceValue::isAliased(const MachineFrameInfo *MFI) const {
94  if (this == getStack() ||
95      this == getGOT() ||
96      this == getConstantPool() ||
97      this == getJumpTable())
98    return false;
99  llvm_unreachable("Unknown PseudoSourceValue!");
100  return true;
101}
102
103bool PseudoSourceValue::mayAlias(const MachineFrameInfo *MFI) const {
104  if (this == getGOT() ||
105      this == getConstantPool() ||
106      this == getJumpTable())
107    return false;
108  return true;
109}
110
111bool FixedStackPseudoSourceValue::isConstant(const MachineFrameInfo *MFI) const{
112  return MFI && MFI->isImmutableObjectIndex(FI);
113}
114
115bool FixedStackPseudoSourceValue::isAliased(const MachineFrameInfo *MFI) const {
116  // Negative frame indices are used for special things that don't
117  // appear in LLVM IR. Non-negative indices may be used for things
118  // like static allocas.
119  if (!MFI)
120    return FI >= 0;
121  // Spill slots should not alias others.
122  return !MFI->isFixedObjectIndex(FI) && !MFI->isSpillSlotObjectIndex(FI);
123}
124
125bool FixedStackPseudoSourceValue::mayAlias(const MachineFrameInfo *MFI) const {
126  if (!MFI)
127    return true;
128  // Spill slots will not alias any LLVM IR value.
129  return !MFI->isSpillSlotObjectIndex(FI);
130}
131
132void FixedStackPseudoSourceValue::printCustom(raw_ostream &OS) const {
133  OS << "FixedStack" << FI;
134}
135