summaryrefslogtreecommitdiffstats
path: root/clang/CodeGen
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-06-22 18:48:09 +0000
committerChris Lattner <sabre@nondot.org>2007-06-22 18:48:09 +0000
commit09153c0a8c949909b5dc29671e668a71affee6bb (patch)
tree06c217109a40b59e8777b060a98f066fefe8ca47 /clang/CodeGen
parent3e3a1e9cda72e795547e930968b8b5c006ff8cd5 (diff)
downloadbcm5719-llvm-09153c0a8c949909b5dc29671e668a71affee6bb.tar.gz
bcm5719-llvm-09153c0a8c949909b5dc29671e668a71affee6bb.zip
Build enough support for aggregates to be able to compile this:
void test(int A, _Complex float Y) { _Complex float X; X = X; } llvm-svn: 39669
Diffstat (limited to 'clang/CodeGen')
-rw-r--r--clang/CodeGen/CGExpr.cpp58
-rw-r--r--clang/CodeGen/CodeGenFunction.h7
-rw-r--r--clang/CodeGen/CodeGenModule.cpp15
-rw-r--r--clang/CodeGen/CodeGenModule.h4
4 files changed, 69 insertions, 15 deletions
diff --git a/clang/CodeGen/CGExpr.cpp b/clang/CodeGen/CGExpr.cpp
index 06e253e3601..1de2ab87e90 100644
--- a/clang/CodeGen/CGExpr.cpp
+++ b/clang/CodeGen/CGExpr.cpp
@@ -231,7 +231,16 @@ RValue CodeGenFunction::EmitLoadOfLValue(const Expr *E) {
// FIXME: this is silly and obviously wrong for non-scalars.
assert(!LV.isBitfield());
- return RValue::get(Builder.CreateLoad(LV.getAddress(), "tmp"));
+ llvm::Value *Ptr = LV.getAddress();
+ const llvm::Type *EltTy =
+ cast<llvm::PointerType>(Ptr->getType())->getElementType();
+
+ // Simple scalar l-value.
+ if (EltTy->isFirstClassType())
+ return RValue::get(Builder.CreateLoad(Ptr, "tmp"));
+
+ // Otherwise, we have an aggregate lvalue.
+ return RValue::getAggregate(Ptr);
}
/// EmitStoreThroughLValue - Store the specified rvalue into the specified
@@ -239,20 +248,43 @@ RValue CodeGenFunction::EmitLoadOfLValue(const Expr *E) {
/// is 'Ty'.
void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
QualType Ty) {
- // FIXME: This is obviously bogus.
assert(!Dst.isBitfield() && "FIXME: Don't support store to bitfield yet");
- assert(Src.isScalar() && "FIXME: Don't support store of aggregate yet");
- // TODO: Handle volatility etc.
- llvm::Value *Addr = Dst.getAddress();
- const llvm::Type *SrcTy = Src.getVal()->getType();
- const llvm::Type *AddrTy =
- cast<llvm::PointerType>(Addr->getType())->getElementType();
+ llvm::Value *DstAddr = Dst.getAddress();
+ if (Src.isScalar()) {
+ // FIXME: Handle volatility etc.
+ const llvm::Type *SrcTy = Src.getVal()->getType();
+ const llvm::Type *AddrTy =
+ cast<llvm::PointerType>(DstAddr->getType())->getElementType();
+
+ if (AddrTy != SrcTy)
+ DstAddr = Builder.CreateBitCast(DstAddr, llvm::PointerType::get(SrcTy),
+ "storetmp");
+ Builder.CreateStore(Src.getVal(), DstAddr);
+ return;
+ }
+
+ // Aggregate assignment turns into llvm.memcpy.
+ const llvm::Type *SBP = llvm::PointerType::get(llvm::Type::Int8Ty);
+ llvm::Value *SrcAddr = Src.getAggregateAddr();
+
+ if (DstAddr->getType() != SBP)
+ DstAddr = Builder.CreateBitCast(DstAddr, SBP, "tmp");
+ if (SrcAddr->getType() != SBP)
+ SrcAddr = Builder.CreateBitCast(SrcAddr, SBP, "tmp");
+
+ unsigned Align = 1; // FIXME: Compute type alignments.
+ unsigned Size = 1234; // FIXME: Compute type sizes.
+
+ // FIXME: Handle variable sized types.
+ const llvm::Type *IntPtr = llvm::IntegerType::get(LLVMPointerWidth);
+ llvm::Value *SizeVal = llvm::ConstantInt::get(IntPtr, Size);
+
+ llvm::Value *MemCpyOps[4] = {
+ DstAddr, SrcAddr, SizeVal,llvm::ConstantInt::get(llvm::Type::Int32Ty, Align)
+ };
- if (AddrTy != SrcTy)
- Addr = Builder.CreateBitCast(Addr, llvm::PointerType::get(SrcTy),
- "storetmp");
- Builder.CreateStore(Src.getVal(), Addr);
+ Builder.CreateCall(CGM.getMemCpyFn(), MemCpyOps, 4);
}
@@ -402,7 +434,7 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) {
if (ArgVal.isScalar())
Args.push_back(ArgVal.getVal());
else // Pass by-address. FIXME: Set attribute bit on call.
- Args.push_back(ArgVal.getAggregateVal());
+ Args.push_back(ArgVal.getAggregateAddr());
}
llvm::Value *V = Builder.CreateCall(Callee, &Args[0], Args.size());
diff --git a/clang/CodeGen/CodeGenFunction.h b/clang/CodeGen/CodeGenFunction.h
index 0870fcd6ccb..683cdfbd491 100644
--- a/clang/CodeGen/CodeGenFunction.h
+++ b/clang/CodeGen/CodeGenFunction.h
@@ -68,6 +68,9 @@ class RValue {
// TODO: Encode this into the low bit of pointer for more efficient
// return-by-value.
bool IsAggregate;
+
+ // FIXME: Aggregate rvalues need to retain information about whether they are
+ // volatile or not.
public:
bool isAggregate() const { return IsAggregate; }
@@ -79,8 +82,8 @@ public:
return V;
}
- /// getAggregateVal() - Return the Value* of the address of the aggregate.
- llvm::Value *getAggregateVal() const {
+ /// getAggregateAddr() - Return the Value* of the address of the aggregate.
+ llvm::Value *getAggregateAddr() const {
assert(isAggregate() && "Not an aggregate!");
return V;
}
diff --git a/clang/CodeGen/CodeGenModule.cpp b/clang/CodeGen/CodeGenModule.cpp
index d4068c67532..4f7834ed55a 100644
--- a/clang/CodeGen/CodeGenModule.cpp
+++ b/clang/CodeGen/CodeGenModule.cpp
@@ -15,9 +15,11 @@
#include "CodeGenFunction.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
+#include "clang/Basic/TargetInfo.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/GlobalVariable.h"
+#include "llvm/Intrinsics.h"
using namespace clang;
using namespace CodeGen;
@@ -51,3 +53,16 @@ void CodeGenModule::EmitFunction(FunctionDecl *FD) {
if (FD->getBody())
CodeGenFunction(*this).GenerateCode(FD);
}
+
+
+
+llvm::Function *CodeGenModule::getMemCpyFn() {
+ if (MemCpyFn) return MemCpyFn;
+ llvm::Intrinsic::ID IID;
+ switch (Context.Target.getPointerWidth(SourceLocation())) {
+ default: assert(0 && "Unknown ptr width");
+ case 32: IID = llvm::Intrinsic::memcpy_i32; break;
+ case 64: IID = llvm::Intrinsic::memcpy_i64; break;
+ }
+ return MemCpyFn = llvm::Intrinsic::getDeclaration(&TheModule, IID);
+}
diff --git a/clang/CodeGen/CodeGenModule.h b/clang/CodeGen/CodeGenModule.h
index 8e40483bd57..885fb97a9f5 100644
--- a/clang/CodeGen/CodeGenModule.h
+++ b/clang/CodeGen/CodeGenModule.h
@@ -20,6 +20,7 @@
namespace llvm {
class Module;
class Constant;
+ class Function;
}
namespace clang {
@@ -36,6 +37,7 @@ class CodeGenModule {
llvm::Module &TheModule;
CodeGenTypes Types;
+ llvm::Function *MemCpyFn;
llvm::DenseMap<const Decl*, llvm::Constant*> GlobalDeclMap;
public:
CodeGenModule(ASTContext &C, llvm::Module &M);
@@ -46,6 +48,8 @@ public:
llvm::Constant *GetAddrOfGlobalDecl(const Decl *D);
+ llvm::Function *getMemCpyFn();
+
void EmitFunction(FunctionDecl *FD);
void PrintStats() {}
OpenPOWER on IntegriCloud