Skip to content

Commit

Permalink
A different approach to shifting Attributes forward
Browse files Browse the repository at this point in the history
  • Loading branch information
troels committed Aug 25, 2021
1 parent d130512 commit 2ef9b36
Showing 1 changed file with 29 additions and 12 deletions.
41 changes: 29 additions & 12 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5172,24 +5172,41 @@ static Function* gen_cfun_wrapper(
std::vector<Type*> fargt_sig(sig.fargt_sig);

fargt_sig.insert(fargt_sig.begin() + sig.sret, T_pprjlvalue);

// Shift LLVM attributes for parameters one to the right, as
// we are adding the extra nest parameter after sret arg.
// AttributeList has function attributes and return value
// attributes before the parameter attributes.
if (attributes.getNumAttrSets() > static_cast<unsigned>(2 + sig.sret)) {
AttrBuilder toShift;
// Skip past function and return and sret attributes to the first real parameter
for (auto it = attributes.index_begin() + 2 + sig.sret; it != attributes.index_end(); ++it) {
AttrBuilder toShiftTemp(attributes.getAttributes(it));
attributes = attributes.removeAttributes(jl_LLVMContext, it);
attributes = attributes.addAttributes(jl_LLVMContext, it, toShift);
toShift = std::move(toShiftTemp);
std::vector<std::pair<unsigned, AttributeSet>> newAttributes;
newAttributes.reserve(attributes.getNumAttrSets() + 1);
auto it = attributes.index_begin();

// Skip past non-parameter attributes (and perhaps parameter return)
// Beware that function index is ~0U, so can't just replace with <
for (;it != attributes.index_end(); ++it) {
if (it != AttributeList::AttrIndex::FunctionIndex &&
it >= AttributeList::AttrIndex::FirstArgIndex + sig.sret) {
break;
}
attributes = attributes.addAttributes(jl_LLVMContext, attributes.index_end(), toShift);
newAttributes.push_back(std::make_pair(it, attributes.getAttributes(it)));
}

// Skip ahead to first parameter (where we may already be, but aren't necessarily)
it = AttributeList::AttrIndex::FirstArgIndex + sig.sret;

// Add the new nest attribute
AttrBuilder attrBuilder;
attrBuilder.addAttribute(Attribute::Nest);
AttributeSet set(AttributeSet::get(jl_LLVMContext, attrBuilder));
newAttributes.push_back(std::make_pair(it, set));

// Shift forward the rest of the attributes
// We are now past the magic numbers, so < is ok here.
for(;it < attributes.index_end(); ++it) {
newAttributes.push_back(std::make_pair(it + 1, attributes.getAttributes(it)));
}

// Create the new AttributeList
attributes = AttributeList::get(jl_LLVMContext, newAttributes);
functype = FunctionType::get(sig.sret ? T_void : sig.prt, fargt_sig, /*isVa*/false);
attributes = attributes.addAttribute(jl_LLVMContext, 1 + sig.sret, Attribute::Nest);
}
else {
functype = sig.functype();
Expand Down

0 comments on commit 2ef9b36

Please sign in to comment.