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.
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)
Addr = Builder.CreateBitCast(Addr, llvm::PointerType::get(SrcTy),
"storetmp");
Builder.CreateStore(Src.getVal(), Addr);
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)
};
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());

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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() {}