summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGBuiltin.cpp
diff options
context:
space:
mode:
authorMichael Zolotukhin <mzolotukhin@apple.com>2015-09-08 23:52:33 +0000
committerMichael Zolotukhin <mzolotukhin@apple.com>2015-09-08 23:52:33 +0000
commit84df12375cdec370fd09a99e3de2e788351ff403 (patch)
treee1f89510fbda184151560b0c8246103ff7d5f7c9 /clang/lib/CodeGen/CGBuiltin.cpp
parent00691e3169fc90e4202c6a592e9fda20e006c299 (diff)
downloadbcm5719-llvm-84df12375cdec370fd09a99e3de2e788351ff403.tar.gz
bcm5719-llvm-84df12375cdec370fd09a99e3de2e788351ff403.zip
Introduce __builtin_nontemporal_store and __builtin_nontemporal_load.
Summary: Currently clang provides no general way to generate nontemporal loads/stores. There are some architecture specific builtins for doing so (e.g. in x86), but there is no way to generate non-temporal store on, e.g. AArch64. This patch adds generic builtins which are expanded to a simple store with '!nontemporal' attribute in IR. Differential Revision: http://reviews.llvm.org/D12313 llvm-svn: 247104
Diffstat (limited to 'clang/lib/CodeGen/CGBuiltin.cpp')
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp26
1 files changed, 26 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index c35f25ad103..729c0a18b06 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -111,6 +111,28 @@ static Value *MakeBinaryAtomicValue(CodeGenFunction &CGF,
return EmitFromInt(CGF, Result, T, ValueType);
}
+static Value *EmitNontemporalStore(CodeGenFunction &CGF, const CallExpr *E) {
+ Value *Val = CGF.EmitScalarExpr(E->getArg(0));
+ Value *Address = CGF.EmitScalarExpr(E->getArg(1));
+
+ // Convert the type of the pointer to a pointer to the stored type.
+ Val = CGF.EmitToMemory(Val, E->getArg(0)->getType());
+ Value *BC = CGF.Builder.CreateBitCast(
+ Address, llvm::PointerType::getUnqual(Val->getType()), "cast");
+ LValue LV = CGF.MakeNaturalAlignAddrLValue(BC, E->getArg(0)->getType());
+ LV.setNontemporal(true);
+ CGF.EmitStoreOfScalar(Val, LV, false);
+ return nullptr;
+}
+
+static Value *EmitNontemporalLoad(CodeGenFunction &CGF, const CallExpr *E) {
+ Value *Address = CGF.EmitScalarExpr(E->getArg(0));
+
+ LValue LV = CGF.MakeNaturalAlignAddrLValue(Address, E->getType());
+ LV.setNontemporal(true);
+ return CGF.EmitLoadOfScalar(LV, E->getExprLoc());
+}
+
static RValue EmitBinaryAtomic(CodeGenFunction &CGF,
llvm::AtomicRMWInst::BinOp Kind,
const CallExpr *E) {
@@ -1143,6 +1165,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
return RValue::get(nullptr);
}
+ case Builtin::BI__builtin_nontemporal_load:
+ return RValue::get(EmitNontemporalLoad(*this, E));
+ case Builtin::BI__builtin_nontemporal_store:
+ return RValue::get(EmitNontemporalStore(*this, E));
case Builtin::BI__c11_atomic_is_lock_free:
case Builtin::BI__atomic_is_lock_free: {
// Call "bool __atomic_is_lock_free(size_t size, void *ptr)". For the
OpenPOWER on IntegriCloud