1193323Sed//===-- llvm/CodeGen/PseudoSourceValue.cpp ----------------------*- C++ -*-===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file implements the PseudoSourceValue class.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14252723Sdim#include "llvm/CodeGen/PseudoSourceValue.h"
15193323Sed#include "llvm/CodeGen/MachineFrameInfo.h"
16252723Sdim#include "llvm/IR/DerivedTypes.h"
17252723Sdim#include "llvm/IR/LLVMContext.h"
18198090Srdivacky#include "llvm/Support/ErrorHandling.h"
19193323Sed#include "llvm/Support/ManagedStatic.h"
20252723Sdim#include "llvm/Support/Mutex.h"
21193323Sed#include "llvm/Support/raw_ostream.h"
22193323Sed#include <map>
23193323Sedusing namespace llvm;
24193323Sed
25204792Srdivackynamespace {
26204792Srdivackystruct PSVGlobalsTy {
27204792Srdivacky  // PseudoSourceValues are immutable so don't need locking.
28204792Srdivacky  const PseudoSourceValue PSVs[4];
29204792Srdivacky  sys::Mutex Lock;  // Guards FSValues, but not the values inside it.
30204792Srdivacky  std::map<int, const PseudoSourceValue *> FSValues;
31193323Sed
32204792Srdivacky  PSVGlobalsTy() : PSVs() {}
33204792Srdivacky  ~PSVGlobalsTy() {
34204792Srdivacky    for (std::map<int, const PseudoSourceValue *>::iterator
35204792Srdivacky           I = FSValues.begin(), E = FSValues.end(); I != E; ++I) {
36204792Srdivacky      delete I->second;
37204792Srdivacky    }
38204792Srdivacky  }
39204792Srdivacky};
40204792Srdivacky
41204792Srdivackystatic ManagedStatic<PSVGlobalsTy> PSVGlobals;
42204792Srdivacky
43204792Srdivacky}  // anonymous namespace
44204792Srdivacky
45193323Sedconst PseudoSourceValue *PseudoSourceValue::getStack()
46204792Srdivacky{ return &PSVGlobals->PSVs[0]; }
47193323Sedconst PseudoSourceValue *PseudoSourceValue::getGOT()
48204792Srdivacky{ return &PSVGlobals->PSVs[1]; }
49193323Sedconst PseudoSourceValue *PseudoSourceValue::getJumpTable()
50204792Srdivacky{ return &PSVGlobals->PSVs[2]; }
51193323Sedconst PseudoSourceValue *PseudoSourceValue::getConstantPool()
52204792Srdivacky{ return &PSVGlobals->PSVs[3]; }
53193323Sed
54193323Sedstatic const char *const PSVNames[] = {
55193323Sed  "Stack",
56193323Sed  "GOT",
57193323Sed  "JumpTable",
58193323Sed  "ConstantPool"
59193323Sed};
60193323Sed
61198090Srdivacky// FIXME: THIS IS A HACK!!!!
62198090Srdivacky// Eventually these should be uniqued on LLVMContext rather than in a managed
63198090Srdivacky// static.  For now, we can safely use the global context for the time being to
64198090Srdivacky// squeak by.
65199481SrdivackyPseudoSourceValue::PseudoSourceValue(enum ValueTy Subclass) :
66198090Srdivacky  Value(Type::getInt8PtrTy(getGlobalContext()),
67199481Srdivacky        Subclass) {}
68193323Sed
69198090Srdivackyvoid PseudoSourceValue::printCustom(raw_ostream &O) const {
70204792Srdivacky  O << PSVNames[this - PSVGlobals->PSVs];
71193323Sed}
72193323Sed
73193323Sedconst PseudoSourceValue *PseudoSourceValue::getFixedStack(int FI) {
74204792Srdivacky  PSVGlobalsTy &PG = *PSVGlobals;
75204792Srdivacky  sys::ScopedLock locked(PG.Lock);
76204792Srdivacky  const PseudoSourceValue *&V = PG.FSValues[FI];
77193323Sed  if (!V)
78193323Sed    V = new FixedStackPseudoSourceValue(FI);
79193323Sed  return V;
80193323Sed}
81193323Sed
82193323Sedbool PseudoSourceValue::isConstant(const MachineFrameInfo *) const {
83193323Sed  if (this == getStack())
84193323Sed    return false;
85193323Sed  if (this == getGOT() ||
86193323Sed      this == getConstantPool() ||
87193323Sed      this == getJumpTable())
88193323Sed    return true;
89198090Srdivacky  llvm_unreachable("Unknown PseudoSourceValue!");
90193323Sed}
91193323Sed
92198396Srdivackybool PseudoSourceValue::isAliased(const MachineFrameInfo *MFI) const {
93198396Srdivacky  if (this == getStack() ||
94198396Srdivacky      this == getGOT() ||
95198396Srdivacky      this == getConstantPool() ||
96198396Srdivacky      this == getJumpTable())
97198396Srdivacky    return false;
98198396Srdivacky  llvm_unreachable("Unknown PseudoSourceValue!");
99198396Srdivacky}
100198396Srdivacky
101198892Srdivackybool PseudoSourceValue::mayAlias(const MachineFrameInfo *MFI) const {
102198892Srdivacky  if (this == getGOT() ||
103198892Srdivacky      this == getConstantPool() ||
104198892Srdivacky      this == getJumpTable())
105198892Srdivacky    return false;
106198892Srdivacky  return true;
107198892Srdivacky}
108198892Srdivacky
109193323Sedbool FixedStackPseudoSourceValue::isConstant(const MachineFrameInfo *MFI) const{
110193323Sed  return MFI && MFI->isImmutableObjectIndex(FI);
111193323Sed}
112198396Srdivacky
113198396Srdivackybool FixedStackPseudoSourceValue::isAliased(const MachineFrameInfo *MFI) const {
114198396Srdivacky  // Negative frame indices are used for special things that don't
115198396Srdivacky  // appear in LLVM IR. Non-negative indices may be used for things
116198396Srdivacky  // like static allocas.
117198396Srdivacky  if (!MFI)
118198396Srdivacky    return FI >= 0;
119198396Srdivacky  // Spill slots should not alias others.
120198396Srdivacky  return !MFI->isFixedObjectIndex(FI) && !MFI->isSpillSlotObjectIndex(FI);
121198396Srdivacky}
122198892Srdivacky
123198892Srdivackybool FixedStackPseudoSourceValue::mayAlias(const MachineFrameInfo *MFI) const {
124198892Srdivacky  if (!MFI)
125198892Srdivacky    return true;
126198892Srdivacky  // Spill slots will not alias any LLVM IR value.
127198892Srdivacky  return !MFI->isSpillSlotObjectIndex(FI);
128198892Srdivacky}
129199481Srdivacky
130199481Srdivackyvoid FixedStackPseudoSourceValue::printCustom(raw_ostream &OS) const {
131199481Srdivacky  OS << "FixedStack" << FI;
132199481Srdivacky}
133