OLD | NEW |
1 //===- ExpandByVal.cpp - Expand out use of "byval" and "sret" attributes---===// | 1 //===- ExpandByVal.cpp - Expand out use of "byval" and "sret" attributes---===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This pass expands out by-value passing of structs as arguments and | 10 // This pass expands out by-value passing of structs as arguments and |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 for (unsigned Slot = 0; Slot < Attrs.getNumSlots(); ++Slot) { | 75 for (unsigned Slot = 0; Slot < Attrs.getNumSlots(); ++Slot) { |
76 unsigned Index = Attrs.getSlotIndex(Slot); | 76 unsigned Index = Attrs.getSlotIndex(Slot); |
77 AttrBuilder AB; | 77 AttrBuilder AB; |
78 for (AttributeSet::iterator Attr = Attrs.begin(Slot), E = Attrs.end(Slot); | 78 for (AttributeSet::iterator Attr = Attrs.begin(Slot), E = Attrs.end(Slot); |
79 Attr != E; ++Attr) { | 79 Attr != E; ++Attr) { |
80 if (!Attr->isAlignAttribute() && | 80 if (!Attr->isAlignAttribute() && |
81 Attr->getKindAsEnum() != Attribute::ByVal && | 81 Attr->getKindAsEnum() != Attribute::ByVal && |
82 Attr->getKindAsEnum() != Attribute::StructRet) { | 82 Attr->getKindAsEnum() != Attribute::StructRet) { |
83 AB.addAttribute(*Attr); | 83 AB.addAttribute(*Attr); |
84 } | 84 } |
| 85 // IR semantics require that ByVal implies NoAlias. However, IR |
| 86 // semantics do not require StructRet to imply NoAlias. For |
| 87 // example, a global variable address can be passed as a |
| 88 // StructRet argument, although Clang does not do so and Clang |
| 89 // explicitly adds NoAlias to StructRet arguments. |
| 90 if (Attr->getKindAsEnum() == Attribute::ByVal) { |
| 91 AB.addAttribute(Attribute::get(Context, Attribute::NoAlias)); |
| 92 } |
85 } | 93 } |
86 AttrList.push_back(AttributeSet::get(Context, Index, AB)); | 94 AttrList.push_back(AttributeSet::get(Context, Index, AB)); |
87 } | 95 } |
88 return AttributeSet::get(Context, AttrList); | 96 return AttributeSet::get(Context, AttrList); |
89 } | 97 } |
90 | 98 |
91 // ExpandCall() can take a CallInst or an InvokeInst. It returns | 99 // ExpandCall() can take a CallInst or an InvokeInst. It returns |
92 // whether the instruction was modified. | 100 // whether the instruction was modified. |
93 template <class InstType> | 101 template <class InstType> |
94 static bool ExpandCall(DataLayout *DL, InstType *Call) { | 102 static bool ExpandCall(DataLayout *DL, InstType *Call) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 } | 190 } |
183 } | 191 } |
184 } | 192 } |
185 | 193 |
186 return Modified; | 194 return Modified; |
187 } | 195 } |
188 | 196 |
189 ModulePass *llvm::createExpandByValPass() { | 197 ModulePass *llvm::createExpandByValPass() { |
190 return new ExpandByVal(); | 198 return new ExpandByVal(); |
191 } | 199 } |
OLD | NEW |