aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Module.cpp
diff options
context:
space:
mode:
authorMomchil Velikov <momchil.velikov@arm.com>2022-02-14 13:41:34 +0000
committerMomchil Velikov <momchil.velikov@arm.com>2022-02-14 14:35:02 +0000
commit6398903ac8c141820a84f3063b7956abe1742500 (patch)
tree48183beaacc70330b9fc79a1a5942022dc631f99 /llvm/lib/IR/Module.cpp
parent48f188433335846bba4cf3e5e9fa2150d4c0253b (diff)
downloadllvm-6398903ac8c141820a84f3063b7956abe1742500.zip
llvm-6398903ac8c141820a84f3063b7956abe1742500.tar.gz
llvm-6398903ac8c141820a84f3063b7956abe1742500.tar.bz2
Extend the `uwtable` attribute with unwind table kind
We have the `clang -cc1` command-line option `-funwind-tables=1|2` and the codegen option `VALUE_CODEGENOPT(UnwindTables, 2, 0) ///< Unwind tables (1) or asynchronous unwind tables (2)`. However, this is encoded in LLVM IR by the presence or the absence of the `uwtable` attribute, i.e. we lose the information whether to generate want just some unwind tables or asynchronous unwind tables. Asynchronous unwind tables take more space in the runtime image, I'd estimate something like 80-90% more, as the difference is adding roughly the same number of CFI directives as for prologues, only a bit simpler (e.g. `.cfi_offset reg, off` vs. `.cfi_restore reg`). Or even more, if you consider tail duplication of epilogue blocks. Asynchronous unwind tables could also restrict code generation to having only a finite number of frame pointer adjustments (an example of *not* having a finite number of `SP` adjustments is on AArch64 when untagging the stack (MTE) in some cases the compiler can modify `SP` in a loop). Having the CFI precise up to an instruction generally also means one cannot bundle together CFI instructions once the prologue is done, they need to be interspersed with ordinary instructions, which means extra `DW_CFA_advance_loc` commands, further increasing the unwind tables size. That is to say, async unwind tables impose a non-negligible overhead, yet for the most common use cases (like C++ exceptions), they are not even needed. This patch extends the `uwtable` attribute with an optional value: - `uwtable` (default to `async`) - `uwtable(sync)`, synchronous unwind tables - `uwtable(async)`, asynchronous (instruction precise) unwind tables Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D114543
Diffstat (limited to 'llvm/lib/IR/Module.cpp')
-rw-r--r--llvm/lib/IR/Module.cpp11
1 files changed, 7 insertions, 4 deletions
diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp
index 6156edd..b66a99b 100644
--- a/llvm/lib/IR/Module.cpp
+++ b/llvm/lib/IR/Module.cpp
@@ -671,12 +671,15 @@ void Module::setRtLibUseGOT() {
addModuleFlag(ModFlagBehavior::Max, "RtLibUseGOT", 1);
}
-bool Module::getUwtable() const {
- auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("uwtable"));
- return Val && (cast<ConstantInt>(Val->getValue())->getZExtValue() > 0);
+UWTableKind Module::getUwtable() const {
+ if (auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("uwtable")))
+ return UWTableKind(cast<ConstantInt>(Val->getValue())->getZExtValue());
+ return UWTableKind::None;
}
-void Module::setUwtable() { addModuleFlag(ModFlagBehavior::Max, "uwtable", 1); }
+void Module::setUwtable(UWTableKind Kind) {
+ addModuleFlag(ModFlagBehavior::Max, "uwtable", uint32_t(Kind));
+}
FramePointerKind Module::getFramePointer() const {
auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("frame-pointer"));