Skip to content

Commit 0d6ed7f

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

File tree

1 file changed

+28
-12
lines changed

1 file changed

+28
-12
lines changed

src/codegen.cpp

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5182,24 +5182,40 @@ 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.emplace_back(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+
newAttributes.emplace_back(it, AttributeSet::get(jl_LLVMContext, attrBuilder));
5209+
5210+
// Shift forward the rest of the attributes
5211+
// We are now past the magic numbers, so < is ok here.
5212+
for(;it < attributes.index_end(); ++it) {
5213+
newAttributes.emplace_back(it + 1, attributes.getAttributes(it));
51995214
}
52005215

5216+
// Create the new AttributeList
5217+
attributes = AttributeList::get(jl_LLVMContext, newAttributes);
52015218
functype = FunctionType::get(sig.sret ? T_void : sig.prt, fargt_sig, /*isVa*/false);
5202-
attributes = attributes.addAttribute(jl_LLVMContext, 1 + sig.sret, Attribute::Nest);
52035219
}
52045220
else {
52055221
functype = sig.functype();

0 commit comments

Comments
 (0)