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
This commit is contained in:
Chris Lattner 2007-06-22 18:48:09 +00:00
parent 3e3a1e9cda
commit 09153c0a8c
4 changed files with 69 additions and 15 deletions

View File

@ -231,7 +231,16 @@ RValue CodeGenFunction::EmitLoadOfLValue(const Expr *E) {
// FIXME: this is silly and obviously wrong for non-scalars. // FIXME: this is silly and obviously wrong for non-scalars.
assert(!LV.isBitfield()); 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 /// EmitStoreThroughLValue - Store the specified rvalue into the specified
@ -239,20 +248,43 @@ RValue CodeGenFunction::EmitLoadOfLValue(const Expr *E) {
/// is 'Ty'. /// is 'Ty'.
void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
QualType Ty) { QualType Ty) {
// FIXME: This is obviously bogus.
assert(!Dst.isBitfield() && "FIXME: Don't support store to bitfield yet"); 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 *DstAddr = Dst.getAddress();
llvm::Value *Addr = Dst.getAddress(); if (Src.isScalar()) {
const llvm::Type *SrcTy = Src.getVal()->getType(); // FIXME: Handle volatility etc.
const llvm::Type *AddrTy = const llvm::Type *SrcTy = Src.getVal()->getType();
cast<llvm::PointerType>(Addr->getType())->getElementType(); 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;
}
if (AddrTy != SrcTy) // Aggregate assignment turns into llvm.memcpy.
Addr = Builder.CreateBitCast(Addr, llvm::PointerType::get(SrcTy), const llvm::Type *SBP = llvm::PointerType::get(llvm::Type::Int8Ty);
"storetmp"); llvm::Value *SrcAddr = Src.getAggregateAddr();
Builder.CreateStore(Src.getVal(), Addr);
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)
};
Builder.CreateCall(CGM.getMemCpyFn(), MemCpyOps, 4);
} }
@ -402,7 +434,7 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) {
if (ArgVal.isScalar()) if (ArgVal.isScalar())
Args.push_back(ArgVal.getVal()); Args.push_back(ArgVal.getVal());
else // Pass by-address. FIXME: Set attribute bit on call. 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()); llvm::Value *V = Builder.CreateCall(Callee, &Args[0], Args.size());

View File

@ -68,6 +68,9 @@ class RValue {
// TODO: Encode this into the low bit of pointer for more efficient // TODO: Encode this into the low bit of pointer for more efficient
// return-by-value. // return-by-value.
bool IsAggregate; bool IsAggregate;
// FIXME: Aggregate rvalues need to retain information about whether they are
// volatile or not.
public: public:
bool isAggregate() const { return IsAggregate; } bool isAggregate() const { return IsAggregate; }
@ -79,8 +82,8 @@ public:
return V; return V;
} }
/// getAggregateVal() - Return the Value* of the address of the aggregate. /// getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value *getAggregateVal() const { llvm::Value *getAggregateAddr() const {
assert(isAggregate() && "Not an aggregate!"); assert(isAggregate() && "Not an aggregate!");
return V; return V;
} }

View File

@ -15,9 +15,11 @@
#include "CodeGenFunction.h" #include "CodeGenFunction.h"
#include "clang/AST/ASTContext.h" #include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h" #include "clang/AST/Decl.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/DerivedTypes.h" #include "llvm/DerivedTypes.h"
#include "llvm/Function.h" #include "llvm/Function.h"
#include "llvm/GlobalVariable.h" #include "llvm/GlobalVariable.h"
#include "llvm/Intrinsics.h"
using namespace clang; using namespace clang;
using namespace CodeGen; using namespace CodeGen;
@ -51,3 +53,16 @@ void CodeGenModule::EmitFunction(FunctionDecl *FD) {
if (FD->getBody()) if (FD->getBody())
CodeGenFunction(*this).GenerateCode(FD); 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);
}

View File

@ -20,6 +20,7 @@
namespace llvm { namespace llvm {
class Module; class Module;
class Constant; class Constant;
class Function;
} }
namespace clang { namespace clang {
@ -36,6 +37,7 @@ class CodeGenModule {
llvm::Module &TheModule; llvm::Module &TheModule;
CodeGenTypes Types; CodeGenTypes Types;
llvm::Function *MemCpyFn;
llvm::DenseMap<const Decl*, llvm::Constant*> GlobalDeclMap; llvm::DenseMap<const Decl*, llvm::Constant*> GlobalDeclMap;
public: public:
CodeGenModule(ASTContext &C, llvm::Module &M); CodeGenModule(ASTContext &C, llvm::Module &M);
@ -46,6 +48,8 @@ public:
llvm::Constant *GetAddrOfGlobalDecl(const Decl *D); llvm::Constant *GetAddrOfGlobalDecl(const Decl *D);
llvm::Function *getMemCpyFn();
void EmitFunction(FunctionDecl *FD); void EmitFunction(FunctionDecl *FD);
void PrintStats() {} void PrintStats() {}