For long double constants, print an approximation of their value to the .s file to...
[oota-llvm.git] / lib / VMCore / ParameterAttributes.cpp
1 //===-- ParameterAttributes.cpp - Implement ParameterAttrs ----------------===//
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 ParamAttrsList class and ParamAttr utilities.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/ParameterAttributes.h"
15 #include "llvm/DerivedTypes.h"
16 #include "llvm/Support/ManagedStatic.h"
17
18 using namespace llvm;
19
20 static ManagedStatic<FoldingSet<ParamAttrsList> > ParamAttrsLists;
21
22 ParamAttrsList::ParamAttrsList(const ParamAttrsVector &attrVec) 
23   : attrs(attrVec), refCount(0) {
24 }
25
26 ParamAttrsList::~ParamAttrsList() {
27   ParamAttrsLists->RemoveNode(this);
28 }
29
30 uint16_t
31 ParamAttrsList::getParamAttrs(uint16_t Index) const {
32   unsigned limit = attrs.size();
33   for (unsigned i = 0; i < limit && attrs[i].index <= Index; ++i)
34     if (attrs[i].index == Index)
35       return attrs[i].attrs;
36   return ParamAttr::None;
37 }
38
39 bool ParamAttrsList::hasAttrSomewhere(ParameterAttributes attr) const {
40   for (unsigned i = 0, e = attrs.size(); i < e; ++i)
41     if (attrs[i].attrs & attr)
42       return true;
43   return false;
44 }
45
46 std::string 
47 ParamAttrsList::getParamAttrsText(uint16_t Attrs) {
48   std::string Result;
49   if (Attrs & ParamAttr::ZExt)
50     Result += "zeroext ";
51   if (Attrs & ParamAttr::SExt)
52     Result += "signext ";
53   if (Attrs & ParamAttr::NoReturn)
54     Result += "noreturn ";
55   if (Attrs & ParamAttr::NoUnwind)
56     Result += "nounwind ";
57   if (Attrs & ParamAttr::InReg)
58     Result += "inreg ";
59   if (Attrs & ParamAttr::NoAlias)
60     Result += "noalias ";
61   if (Attrs & ParamAttr::StructRet)
62     Result += "sret ";  
63   if (Attrs & ParamAttr::ByVal)
64     Result += "byval ";
65   if (Attrs & ParamAttr::Nest)
66     Result += "nest ";
67   if (Attrs & ParamAttr::ReadNone)
68     Result += "readnone ";
69   if (Attrs & ParamAttr::ReadOnly)
70     Result += "readonly ";
71   return Result;
72 }
73
74 void ParamAttrsList::Profile(FoldingSetNodeID &ID,
75                              const ParamAttrsVector &Attrs) {
76   for (unsigned i = 0; i < Attrs.size(); ++i)
77     ID.AddInteger(unsigned(Attrs[i].attrs) << 16 | unsigned(Attrs[i].index));
78 }
79
80 const ParamAttrsList *
81 ParamAttrsList::get(const ParamAttrsVector &attrVec) {
82   // If there are no attributes then return a null ParamAttrsList pointer.
83   if (attrVec.empty())
84     return 0;
85
86 #ifndef NDEBUG
87   for (unsigned i = 0, e = attrVec.size(); i < e; ++i) {
88     assert(attrVec[i].attrs != ParamAttr::None
89            && "Pointless parameter attribute!");
90     assert((!i || attrVec[i-1].index < attrVec[i].index)
91            && "Misordered ParamAttrsList!");
92   }
93 #endif
94
95   // Otherwise, build a key to look up the existing attributes.
96   FoldingSetNodeID ID;
97   ParamAttrsList::Profile(ID, attrVec);
98   void *InsertPos;
99   ParamAttrsList *PAL = ParamAttrsLists->FindNodeOrInsertPos(ID, InsertPos);
100
101   // If we didn't find any existing attributes of the same shape then
102   // create a new one and insert it.
103   if (!PAL) {
104     PAL = new ParamAttrsList(attrVec);
105     ParamAttrsLists->InsertNode(PAL, InsertPos);
106   }
107
108   // Return the ParamAttrsList that we found or created.
109   return PAL;
110 }
111
112 const ParamAttrsList *
113 ParamAttrsList::getModified(const ParamAttrsList *PAL,
114                             const ParamAttrsVector &modVec) {
115   if (modVec.empty())
116     return PAL;
117
118 #ifndef NDEBUG
119   for (unsigned i = 0, e = modVec.size(); i < e; ++i)
120     assert((!i || modVec[i-1].index < modVec[i].index)
121            && "Misordered ParamAttrsList!");
122 #endif
123
124   if (!PAL) {
125     // Strip any instances of ParamAttr::None from modVec before calling 'get'.
126     ParamAttrsVector newVec;
127     for (unsigned i = 0, e = modVec.size(); i < e; ++i)
128       if (modVec[i].attrs != ParamAttr::None)
129         newVec.push_back(modVec[i]);
130     return get(newVec);
131   }
132
133   const ParamAttrsVector &oldVec = PAL->attrs;
134
135   ParamAttrsVector newVec;
136   unsigned oldI = 0;
137   unsigned modI = 0;
138   unsigned oldE = oldVec.size();
139   unsigned modE = modVec.size();
140
141   while (oldI < oldE && modI < modE) {
142     uint16_t oldIndex = oldVec[oldI].index;
143     uint16_t modIndex = modVec[modI].index;
144
145     if (oldIndex < modIndex) {
146       newVec.push_back(oldVec[oldI]);
147       ++oldI;
148     } else if (modIndex < oldIndex) {
149       if (modVec[modI].attrs != ParamAttr::None)
150         newVec.push_back(modVec[modI]);
151       ++modI;
152     } else {
153       // Same index - overwrite or delete existing attributes.
154       if (modVec[modI].attrs != ParamAttr::None)
155         newVec.push_back(modVec[modI]);
156       ++oldI;
157       ++modI;
158     }
159   }
160
161   for (; oldI < oldE; ++oldI)
162     newVec.push_back(oldVec[oldI]);
163   for (; modI < modE; ++modI)
164     if (modVec[modI].attrs != ParamAttr::None)
165       newVec.push_back(modVec[modI]);
166
167   return get(newVec);
168 }
169
170 const ParamAttrsList *
171 ParamAttrsList::includeAttrs(const ParamAttrsList *PAL,
172                              uint16_t idx, uint16_t attrs) {
173   uint16_t OldAttrs = PAL ? PAL->getParamAttrs(idx) : 0;
174   uint16_t NewAttrs = OldAttrs | attrs;
175   if (NewAttrs == OldAttrs)
176     return PAL;
177
178   ParamAttrsVector modVec;
179   modVec.push_back(ParamAttrsWithIndex::get(idx, NewAttrs));
180   return getModified(PAL, modVec);
181 }
182
183 const ParamAttrsList *
184 ParamAttrsList::excludeAttrs(const ParamAttrsList *PAL,
185                              uint16_t idx, uint16_t attrs) {
186   uint16_t OldAttrs = PAL ? PAL->getParamAttrs(idx) : 0;
187   uint16_t NewAttrs = OldAttrs & ~attrs;
188   if (NewAttrs == OldAttrs)
189     return PAL;
190
191   ParamAttrsVector modVec;
192   modVec.push_back(ParamAttrsWithIndex::get(idx, NewAttrs));
193   return getModified(PAL, modVec);
194 }
195
196 uint16_t ParamAttr::typeIncompatible (const Type *Ty) {
197   uint16_t Incompatible = None;
198
199   if (!Ty->isInteger())
200     // Attributes that only apply to integers.
201     Incompatible |= SExt | ZExt;
202
203   if (!isa<PointerType>(Ty))
204     // Attributes that only apply to pointers.
205     Incompatible |= ByVal | Nest | NoAlias | StructRet;
206
207   return Incompatible;
208 }