summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorRenato Golin <renato.golin@linaro.org>2014-05-19 18:15:42 +0000
committerRenato Golin <renato.golin@linaro.org>2014-05-19 18:15:42 +0000
commit230c5eb4bde7314331ae5c0bca65087ed504202c (patch)
tree4e74f0d0624a6e259fefce46c6d6c1898b982124 /clang/lib/CodeGen
parent194cfa9b21ef52bb855afab36553daad0ecd7681 (diff)
downloadbcm5719-llvm-230c5eb4bde7314331ae5c0bca65087ed504202c.tar.gz
bcm5719-llvm-230c5eb4bde7314331ae5c0bca65087ed504202c.zip
Non-allocatable Global Named Register
This patch implements global named registers in Clang, lowering to the just created intrinsics in LLVM (@llvm.read/write_register). A new type of LValue had to be created (Register), which just adds support to carry the metadata node containing the name of the register. Two new methods to emit loads and stores interoperate with another to emit the named metadata node. No guarantees are being made and only non-allocatable global variable named registers are being supported. Local named register support is unchanged. llvm-svn: 209149
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp60
-rw-r--r--clang/lib/CodeGen/CGValue.h17
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h3
3 files changed, 77 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 2be47b46e22..4822769f392 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -21,6 +21,7 @@
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Attr.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/IR/DataLayout.h"
@@ -1276,6 +1277,10 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
if (LV.isExtVectorElt())
return EmitLoadOfExtVectorElementLValue(LV);
+ // Global Register variables always invoke intrinsics
+ if (LV.isGlobalReg())
+ return EmitLoadOfGlobalRegLValue(LV);
+
assert(LV.isBitField() && "Unknown LValue type!");
return EmitLoadOfBitfieldLValue(LV);
}
@@ -1343,6 +1348,16 @@ RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV) {
return RValue::get(Vec);
}
+/// @brief Load of global gamed gegisters are always calls to intrinsics.
+RValue CodeGenFunction::EmitLoadOfGlobalRegLValue(LValue LV) {
+ assert(LV.getType()->isIntegerType() && "Bad type for register variable");
+ llvm::MDNode *RegName = dyn_cast<llvm::MDNode>(LV.getGlobalReg());
+ assert(RegName && "Register LValue is not metadata");
+ llvm::Type *Types[] = { CGM.getTypes().ConvertType(LV.getType()) };
+ llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
+ llvm::Value* Call = Builder.CreateCall(F, RegName);
+ return RValue::get(Call);
+}
/// EmitStoreThroughLValue - Store the specified rvalue into the specified
@@ -1370,6 +1385,9 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
if (Dst.isExtVectorElt())
return EmitStoreThroughExtVectorComponentLValue(Src, Dst);
+ if (Dst.isGlobalReg())
+ return EmitStoreThroughGlobalRegLValue(Src, Dst);
+
assert(Dst.isBitField() && "Unknown LValue type");
return EmitStoreThroughBitfieldLValue(Src, Dst);
}
@@ -1581,6 +1599,17 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
Store->setAlignment(Dst.getAlignment().getQuantity());
}
+/// @brief Store of global named registers are always calls to intrinsics.
+void CodeGenFunction::EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst) {
+ assert(Dst.getType()->isIntegerType() && "Bad type for register variable");
+ llvm::MDNode *RegName = dyn_cast<llvm::MDNode>(Dst.getGlobalReg());
+ assert(RegName && "Register LValue is not metadata");
+ llvm::Type *Types[] = { CGM.getTypes().ConvertType(Dst.getType()) };
+ llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
+ llvm::Value *Value = Src.getScalarVal();
+ Builder.CreateCall2(F, RegName, Value);
+}
+
// setObjCGCLValueClass - sets class of he lvalue for the purpose of
// generating write-barries API. It is currently a global, ivar,
// or neither.
@@ -1740,14 +1769,41 @@ static LValue EmitCapturedFieldLValue(CodeGenFunction &CGF, const FieldDecl *FD,
return CGF.EmitLValueForField(LV, FD);
}
+/// Named Registers are named metadata pointing to the register name
+/// which will be read from/written to as an argument to the intrinsic
+/// @llvm.read/write_register.
+/// So far, only the name is being passed down, but other options such as
+/// register type, allocation type or even optimization options could be
+/// passed down via the metadata node.
+static LValue EmitGlobalNamedRegister(const VarDecl *VD,
+ CodeGenModule &CGM,
+ CharUnits Alignment) {
+ AsmLabelAttr *Asm = VD->getAttr<AsmLabelAttr>();
+ llvm::Twine Name("llvm.named.register."+Asm->getLabel());
+ llvm::NamedMDNode *M = CGM.getModule().getOrInsertNamedMetadata(Name.str());
+ if (M->getNumOperands() == 0) {
+ llvm::MDString *Str = llvm::MDString::get(CGM.getLLVMContext(),
+ Asm->getLabel());
+ llvm::Value *Ops[] = { Str };
+ M->addOperand(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
+ }
+ return LValue::MakeGlobalReg(M->getOperand(0), VD->getType(), Alignment);
+}
+
LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
const NamedDecl *ND = E->getDecl();
CharUnits Alignment = getContext().getDeclAlign(ND);
QualType T = E->getType();
+ const auto *VD = dyn_cast<VarDecl>(ND);
+
+ // Global Named registers access via intrinsics only
+ if (VD && VD->getStorageClass() == SC_Register &&
+ VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())
+ return EmitGlobalNamedRegister(VD, CGM, Alignment);
// A DeclRefExpr for a reference initialized by a constant expression can
// appear without being odr-used. Directly emit the constant initializer.
- if (const auto *VD = dyn_cast<VarDecl>(ND)) {
+ if (VD) {
const Expr *Init = VD->getAnyInitializer(VD);
if (Init && !isa<ParmVarDecl>(VD) && VD->getType()->isReferenceType() &&
VD->isUsableInConstantExpressions(getContext()) &&
@@ -1773,7 +1829,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
return MakeAddrLValue(Aliasee, T, Alignment);
}
- if (const auto *VD = dyn_cast<VarDecl>(ND)) {
+ if (VD) {
// Check if this is a global variable.
if (VD->hasLinkage() || VD->isStaticDataMember())
return EmitGlobalVarDeclLValue(*this, E, VD);
diff --git a/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h
index da2a03437d3..3739ae95509 100644
--- a/clang/lib/CodeGen/CGValue.h
+++ b/clang/lib/CodeGen/CGValue.h
@@ -110,7 +110,8 @@ class LValue {
Simple, // This is a normal l-value, use getAddress().
VectorElt, // This is a vector element l-value (V[i]), use getVector*
BitField, // This is a bitfield l-value, use getBitfield*.
- ExtVectorElt // This is an extended vector subset, use getExtVectorComp
+ ExtVectorElt, // This is an extended vector subset, use getExtVectorComp
+ GlobalReg // This is a register l-value, use getGlobalReg()
} LVType;
llvm::Value *V;
@@ -192,6 +193,7 @@ public:
bool isVectorElt() const { return LVType == VectorElt; }
bool isBitField() const { return LVType == BitField; }
bool isExtVectorElt() const { return LVType == ExtVectorElt; }
+ bool isGlobalReg() const { return LVType == GlobalReg; }
bool isVolatileQualified() const { return Quals.hasVolatile(); }
bool isRestrictQualified() const { return Quals.hasRestrict(); }
@@ -286,6 +288,9 @@ public:
return *BitFieldInfo;
}
+ // global register lvalue
+ llvm::Value *getGlobalReg() const { assert(isGlobalReg()); return V; }
+
static LValue MakeAddr(llvm::Value *address, QualType type,
CharUnits alignment, ASTContext &Context,
llvm::MDNode *TBAAInfo = 0) {
@@ -336,6 +341,16 @@ public:
return R;
}
+ static LValue MakeGlobalReg(llvm::Value *Reg,
+ QualType type,
+ CharUnits Alignment) {
+ LValue R;
+ R.LVType = GlobalReg;
+ R.V = Reg;
+ R.Initialize(type, type.getQualifiers(), Alignment);
+ return R;
+ }
+
RValue asAggregateRValue() const {
// FIMXE: Alignment
return RValue::getAggregate(getAddress(), isVolatileQualified());
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 6af7a98d96e..c859ddab773 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -1979,12 +1979,14 @@ public:
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc);
RValue EmitLoadOfExtVectorElementLValue(LValue V);
RValue EmitLoadOfBitfieldLValue(LValue LV);
+ RValue EmitLoadOfGlobalRegLValue(LValue LV);
/// EmitStoreThroughLValue - Store the specified rvalue into the specified
/// lvalue, where both are guaranteed to the have the same type, and that type
/// is 'Ty'.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false);
void EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst);
+ void EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst);
/// EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints
/// as EmitStoreThroughLValue.
@@ -2009,6 +2011,7 @@ public:
// Note: only available for agg return types
LValue EmitVAArgExprLValue(const VAArgExpr *E);
LValue EmitDeclRefLValue(const DeclRefExpr *E);
+ LValue EmitReadRegister(const VarDecl *VD);
LValue EmitStringLiteralLValue(const StringLiteral *E);
LValue EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E);
LValue EmitPredefinedLValue(const PredefinedExpr *E);
OpenPOWER on IntegriCloud