Skip to content

Commit d837255

Browse files
committed
A different approach to shifting Attributes forward
1 parent 5958d91 commit d837255

File tree

1 file changed

+29
-12
lines changed

1 file changed

+29
-12
lines changed

src/codegen.cpp

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5182,24 +5182,41 @@ static Function* gen_cfun_wrapper(
51825182
std::vector<Type*> fargt_sig(sig.fargt_sig);
51835183

51845184
fargt_sig.insert(fargt_sig.begin() + sig.sret, T_pprjlvalue);
5185+
51855186
// Shift LLVM attributes for parameters one to the right, as
51865187
// we are adding the extra nest parameter after sret arg.
5187-
// AttributeList has function attributes and return value
5188-
// attributes before the parameter attributes.
5189-
if (attributes.getNumAttrSets() > static_cast<unsigned>(2 + sig.sret)) {
5190-
AttrBuilder toShift;
5191-
// Skip past function and return and sret attributes to the first real parameter
5192-
for (auto it = attributes.index_begin() + 2 + sig.sret; it != attributes.index_end(); ++it) {
5193-
AttrBuilder toShiftTemp(attributes.getAttributes(it));
5194-
attributes = attributes.removeAttributes(jl_LLVMContext, it);
5195-
attributes = attributes.addAttributes(jl_LLVMContext, it, toShift);
5196-
toShift = std::move(toShiftTemp);
5188+
std::vector<std::pair<unsigned, AttributeSet>> newAttributes;
5189+
newAttributes.reserve(attributes.getNumAttrSets() + 1);
5190+
auto it = attributes.index_begin();
5191+
5192+
// Skip past non-parameter attributes (and perhaps parameter return)
5193+
// Beware that function index is ~0U, so can't just replace with <
5194+
for (;it != attributes.index_end(); ++it) {
5195+
if (it != AttributeList::AttrIndex::FunctionIndex &&
5196+
it >= AttributeList::AttrIndex::FirstArgIndex + sig.sret) {
5197+
break;
51975198
}
5198-
attributes = attributes.addAttributes(jl_LLVMContext, attributes.index_end(), toShift);
5199+
newAttributes.push_back(std::make_pair(it, attributes.getAttributes(it)));
5200+
}
5201+
5202+
// Skip ahead to first parameter (where we may already be, but aren't necessarily)
5203+
it = AttributeList::AttrIndex::FirstArgIndex + sig.sret;
5204+
5205+
// Add the new nest attribute
5206+
AttrBuilder attrBuilder;
5207+
attrBuilder.addAttribute(Attribute::Nest);
5208+
AttributeSet set(AttributeSet::get(jl_LLVMContext, attrBuilder));
5209+
newAttributes.push_back(std::make_pair(it, set));
5210+
5211+
// Shift forward the rest of the attributes
5212+
// We are now past the magic numbers, so < is ok here.
5213+
for(;it < attributes.index_end(); ++it) {
5214+
newAttributes.push_back(std::make_pair(it + 1, attributes.getAttributes(it)));
51995215
}
52005216

5217+
// Create the new AttributeList
5218+
attributes = AttributeList::get(jl_LLVMContext, newAttributes);
52015219
functype = FunctionType::get(sig.sret ? T_void : sig.prt, fargt_sig, /*isVa*/false);
5202-
attributes = attributes.addAttribute(jl_LLVMContext, 1 + sig.sret, Attribute::Nest);
52035220
}
52045221
else {
52055222
functype = sig.functype();

0 commit comments

Comments
 (0)