commit 573f3f8d487dfd1f56ab71b96ad23af1a2d4162e (tree)
parent 07a71fc3221dfba05caea5a50ebe3dac5c76d643
Author: Andrew Kelley <superjoe30@gmail.com>
Date: Mon, 6 Feb 2017 13:50:19 -0500
coldcc works better
* Only use Cold Calling Convention on x86
* Add the cold attribute to functions marked with coldcc
Diffstat:
4 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/src/analyze.cpp b/src/analyze.cpp
@@ -713,12 +713,14 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
fn_type->data.fn.fn_type_id = *fn_type_id;
if (fn_type_id->is_cold) {
- if (g->zig_target.arch.arch == ZigLLVM_arm) {
- // TODO we want to use coldcc here but it's causing a segfault on ARM
- // https://llvm.org/bugs/show_bug.cgi?id=31875
- fn_type->data.fn.calling_convention = LLVMCCallConv;
- } else {
+ // cold calling convention only works on x86.
+ // but we can add the cold attribute later.
+ if (g->zig_target.arch.arch == ZigLLVM_x86 ||
+ g->zig_target.arch.arch == ZigLLVM_x86_64)
+ {
fn_type->data.fn.calling_convention = LLVMColdCallConv;
+ } else {
+ fn_type->data.fn.calling_convention = LLVMFastCallConv;
}
} else if (fn_type_id->is_extern) {
fn_type->data.fn.calling_convention = LLVMCCallConv;
diff --git a/src/codegen.cpp b/src/codegen.cpp
@@ -268,6 +268,9 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
LLVMAddFunctionAttr(fn_table_entry->llvm_value, LLVMNoReturnAttribute);
}
LLVMSetFunctionCallConv(fn_table_entry->llvm_value, fn_type->data.fn.calling_convention);
+ if (fn_type->data.fn.fn_type_id.is_cold) {
+ ZigLLVMAddFunctionAttrCold(fn_table_entry->llvm_value);
+ }
LLVMAddFunctionAttr(fn_table_entry->llvm_value, LLVMNoUnwindAttribute);
if (!g->is_release_build && fn_table_entry->fn_inline != FnInlineAlways) {
ZigLLVMAddFunctionAttr(fn_table_entry->llvm_value, "no-frame-pointer-elim", "true");
diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp
@@ -561,6 +561,14 @@ void ZigLLVMAddFunctionAttr(LLVMValueRef fn_ref, const char *attr_name, const ch
func->setAttributes(new_attr_set);
}
+void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn_ref) {
+ Function *func = unwrap<Function>(fn_ref);
+ const AttributeSet attr_set = func->getAttributes();
+ const AttributeSet new_attr_set = attr_set.addAttribute(func->getContext(), AttributeSet::FunctionIndex,
+ Attribute::Cold);
+ func->setAttributes(new_attr_set);
+}
+
static_assert((Triple::ArchType)ZigLLVM_LastArchType == Triple::LastArchType, "");
static_assert((Triple::VendorType)ZigLLVM_LastVendorType == Triple::LastVendorType, "");
diff --git a/src/zig_llvm.hpp b/src/zig_llvm.hpp
@@ -165,6 +165,7 @@ ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, ZigLLVMDIScop
void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state);
void ZigLLVMAddFunctionAttr(LLVMValueRef fn, const char *attr_name, const char *attr_value);
+void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn);
unsigned ZigLLVMGetPrefTypeAlignment(LLVMTargetDataRef TD, LLVMTypeRef Ty);