diff options
author | Evan Cheng <evan.cheng@apple.com> | 2008-01-11 09:12:49 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2008-01-11 09:12:49 +0000 |
commit | 588c6f8e6c4772e4c5abe58b6fb55cf025503e19 (patch) | |
tree | 437b1ae04aadc57bcea6df5867d71afd01e960ac /lib/Target/CBackend/CBackend.cpp | |
parent | 90e9d4e01335fc083ea9c76873b9a9581a929983 (diff) |
Some C backend ByVal parameter attribute support. Not yet complete.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45864 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/CBackend/CBackend.cpp')
-rw-r--r-- | lib/Target/CBackend/CBackend.cpp | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 23e9b275d8..bbaf9c1bb8 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -87,6 +87,7 @@ namespace { std::map<const Type *, std::string> TypeNames; std::map<const ConstantFP *, unsigned> FPConstantMap; std::set<Function*> intrinsicPrototypesAlreadyGenerated; + std::set<const Value*> ByValParams; public: static char ID; @@ -113,14 +114,16 @@ namespace { printFloatingPointConstants(F); printFunction(F); - FPConstantMap.clear(); return false; } virtual bool doFinalization(Module &M) { // Free memory... delete Mang; + FPConstantMap.clear(); TypeNames.clear(); + intrinsicPrototypesAlreadyGenerated.clear(); + ByValParams.clear(); return false; } @@ -370,6 +373,10 @@ void CWriter::printStructReturnPointerFunctionType(std::ostream &Out, if (PrintedType) FunctionInnards << ", "; const Type *ArgTy = *I; + if (PAL && PAL->paramHasAttr(Idx, ParamAttr::ByVal)) { + assert(isa<PointerType>(ArgTy)); + ArgTy = cast<PointerType>(ArgTy)->getElementType(); + } printType(FunctionInnards, ArgTy, /*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt), ""); PrintedType = true; @@ -1885,6 +1892,12 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) { else ArgName = ""; const Type *ArgTy = I->getType(); + if (PAL && PAL->paramHasAttr(Idx, ParamAttr::ByVal)) { + assert(isa<PointerType>(ArgTy)); + ArgTy = cast<PointerType>(ArgTy)->getElementType(); + const Value *Arg = &(*I); + ByValParams.insert(Arg); + } printType(FunctionInnards, ArgTy, /*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt), ArgName); @@ -2384,6 +2397,13 @@ void CWriter::visitCastInst(CastInst &I) { // Make sure we really get a sext from bool by subtracing the bool from 0 Out << "0-"; } + // If it's a byval parameter being casted, then takes its address. + bool isByVal = ByValParams.count(I.getOperand(0)); + if (isByVal) { + assert(I.getOpcode() == Instruction::BitCast && + "ByVal aggregate parameter must ptr type"); + Out << '&'; + } writeOperand(I.getOperand(0)); if (DstTy == Type::Int1Ty && (I.getOpcode() == Instruction::Trunc || @@ -2675,7 +2695,12 @@ void CWriter::visitCallInst(CallInst &I) { /*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt)); Out << ')'; } - writeOperand(*AI); + // If call is expecting argument to be passed by value, then do not + // take its address. + if (PAL && PAL->paramHasAttr(Idx, ParamAttr::ByVal)) + writeOperandInternal(*AI); + else + writeOperand(*AI); PrintedArg = true; } Out << ')'; @@ -2869,7 +2894,9 @@ void CWriter::printIndexingExpression(Value *Ptr, gep_type_iterator I, // Print out the -> operator if possible... if (TmpI != E && isa<StructType>(*TmpI)) { - Out << (HasImplicitAddress ? "." : "->"); + // Check if it's actually an aggregate parameter passed by value. + bool isByVal = ByValParams.count(Ptr); + Out << ((HasImplicitAddress || isByVal) ? "." : "->"); Out << "field" << cast<ConstantInt>(TmpI.getOperand())->getZExtValue(); I = ++TmpI; } |