diff options
author | Chris Lattner <sabre@nondot.org> | 2007-06-22 18:48:09 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-06-22 18:48:09 +0000 |
commit | 09153c0a8c949909b5dc29671e668a71affee6bb (patch) | |
tree | 06c217109a40b59e8777b060a98f066fefe8ca47 /clang/CodeGen | |
parent | 3e3a1e9cda72e795547e930968b8b5c006ff8cd5 (diff) | |
download | bcm5719-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.cpp | 58 | ||||
-rw-r--r-- | clang/CodeGen/CodeGenFunction.h | 7 | ||||
-rw-r--r-- | clang/CodeGen/CodeGenModule.cpp | 15 | ||||
-rw-r--r-- | clang/CodeGen/CodeGenModule.h | 4 |
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() {} |