-
Notifications
You must be signed in to change notification settings - Fork 14.6k
[lld] Support merging RISC-V Atomics ABI attributes #97347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
b9180d6
bec3514
9678340
682a688
1ddcf1e
b15fab6
b8da02a
030fa6b
5c57d12
0af5e34
8d6afed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1084,10 +1084,76 @@ static void mergeArch(RISCVISAUtils::OrderedExtensionMap &mergedExts, | |
} | ||
} | ||
|
||
static void mergeAtomic(DenseMap<unsigned, unsigned>::iterator it, | ||
const InputSectionBase *oldSection, | ||
const InputSectionBase *newSection, | ||
RISCVAttrs::RISCVAtomicAbiTag oldTag, | ||
RISCVAttrs::RISCVAtomicAbiTag newTag) { | ||
using RISCVAttrs::RISCVAtomicAbiTag; | ||
// Same tags stay the same, and UNKNOWN is compatible with anything | ||
if (oldTag == newTag || newTag == RISCVAtomicAbiTag::UNKNOWN) | ||
return; | ||
|
||
auto reportAbiError = [&]() { | ||
errorOrWarn("atomic abi mismatch for " + oldSection->name + "\n>>> " + | ||
toString(oldSection) + | ||
": atomic_abi=" + Twine(static_cast<unsigned>(oldTag)) + | ||
"\n>>> " + toString(newSection) + | ||
": atomic_abi=" + Twine(static_cast<unsigned>(newTag))); | ||
}; | ||
|
||
switch (static_cast<RISCVAtomicAbiTag>(oldTag)) { | ||
case RISCVAtomicAbiTag::UNKNOWN: | ||
it->getSecond() = static_cast<unsigned>(newTag); | ||
return; | ||
case RISCVAtomicAbiTag::A6C: | ||
switch (newTag) { | ||
case RISCVAtomicAbiTag::A6S: | ||
it->getSecond() = static_cast<unsigned>(RISCVAtomicAbiTag::A6C); | ||
return; | ||
case RISCVAtomicAbiTag::A7: | ||
reportAbiError(); | ||
return; | ||
case RISCVAttrs::RISCVAtomicAbiTag::UNKNOWN: | ||
case RISCVAttrs::RISCVAtomicAbiTag::A6C: | ||
return; | ||
}; | ||
|
||
case RISCVAtomicAbiTag::A6S: | ||
switch (newTag) { | ||
case RISCVAtomicAbiTag::A6C: | ||
it->getSecond() = static_cast<unsigned>(RISCVAtomicAbiTag::A6C); | ||
return; | ||
case RISCVAtomicAbiTag::A7: | ||
it->getSecond() = static_cast<unsigned>(RISCVAtomicAbiTag::A7); | ||
return; | ||
case RISCVAttrs::RISCVAtomicAbiTag::UNKNOWN: | ||
case RISCVAttrs::RISCVAtomicAbiTag::A6S: | ||
return; | ||
}; | ||
|
||
case RISCVAtomicAbiTag::A7: | ||
switch (newTag) { | ||
case RISCVAtomicAbiTag::A6S: | ||
it->getSecond() = static_cast<unsigned>(RISCVAtomicAbiTag::A7); | ||
return; | ||
case RISCVAtomicAbiTag::A6C: | ||
reportAbiError(); | ||
return; | ||
case RISCVAttrs::RISCVAtomicAbiTag::UNKNOWN: | ||
case RISCVAttrs::RISCVAtomicAbiTag::A7: | ||
return; | ||
}; | ||
}; | ||
llvm_unreachable("unknown AtomicABI"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If a potentially-corrupted object file may contain an unknown tag, it's inappropriate to use unreachable. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, fair point. I'll update w/ an error instead. |
||
} | ||
|
||
static RISCVAttributesSection * | ||
mergeAttributesSection(const SmallVector<InputSectionBase *, 0> §ions) { | ||
using RISCVAttrs::RISCVAtomicAbiTag; | ||
RISCVISAUtils::OrderedExtensionMap exts; | ||
const InputSectionBase *firstStackAlign = nullptr; | ||
const InputSectionBase *firstAtomicAbi = nullptr; | ||
unsigned firstStackAlignValue = 0, xlen = 0; | ||
bool hasArch = false; | ||
|
||
|
@@ -1134,6 +1200,18 @@ mergeAttributesSection(const SmallVector<InputSectionBase *, 0> §ions) { | |
case RISCVAttrs::PRIV_SPEC_MINOR: | ||
case RISCVAttrs::PRIV_SPEC_REVISION: | ||
break; | ||
|
||
case RISCVAttrs::AttrType::ATOMIC_ABI: | ||
if (auto i = parser.getAttributeValue(tag.attr)) { | ||
auto r = merged.intAttr.try_emplace(tag.attr, *i); | ||
if (r.second) | ||
firstAtomicAbi = sec; | ||
else | ||
mergeAtomic(r.first, firstAtomicAbi, sec, | ||
static_cast<RISCVAtomicAbiTag>(r.first->getSecond()), | ||
static_cast<RISCVAtomicAbiTag>(*i)); | ||
} | ||
continue; | ||
} | ||
|
||
// Fallback for deprecated priv_spec* and other unknown attributes: retain | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unneeded cast?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. Looks like I missed one. Thanks.