aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/ArrayHandler.cc51
-rw-r--r--lib/CodeGen/CodeGen.cc25
-rw-r--r--lib/CodeGen/TypeSystem.cc4
3 files changed, 53 insertions, 27 deletions
diff --git a/lib/CodeGen/ArrayHandler.cc b/lib/CodeGen/ArrayHandler.cc
index 83204a7..7977563 100644
--- a/lib/CodeGen/ArrayHandler.cc
+++ b/lib/CodeGen/ArrayHandler.cc
@@ -117,14 +117,13 @@ void ArrayHandler::emitArrayDeclare(ArrayDeclareStmtAST *Stmt, CodeGen &CG) {
Meta.Rank = Rank;
Meta.ElementTypeName = ElemInfo->Name;
Meta.ElementType = ElemInfo->LLVMType;
- Meta.ElementSize = ElemInfo->ElementSize;
+ Meta.ElementSizeC = Types.getSizeOfConstant(ElemInfo->LLVMType);
Meta.LowerBounds = std::move(Lows);
Meta.UpperBounds = std::move(Highs);
Meta.Multipliers = std::move(Multipliers);
ArrayTable[Name] = Meta;
- Value *ElemSize = ConstantInt::get(*TheContext, APInt(64, ElemInfo->ElementSize));
- Value *TotalBytes = Builder->CreateMul(TotalElements, ElemSize, Name + "_total_bytes");
+ Value *TotalBytes = Builder->CreateMul(TotalElements, Meta.ElementSizeC, Name + "_total_bytes");
CallInst *Ptr = Builder->CreateCall(MallocFunc, TotalBytes, Name + "_malloc");
FunctionType *MemsetType = FunctionType::get(PointerType::getUnqual(*TheContext),
@@ -179,10 +178,7 @@ Value *ArrayHandler::loadElement(const std::string &Name, Value *Offset, CodeGen
Value *Val = Builder->CreateLoad(Meta->ElementType, ElemPtr, Name + "_elem");
if (Meta->ElementTypeName == "STRING") {
- Value *IsNull = Builder->CreateICmpEQ(Val,
- ConstantPointerNull::get(cast<PointerType>(Meta->ElementType)),
- Name + "_str_is_null");
- Val = Builder->CreateSelect(IsNull, CG.EmptyStringStr, Val, Name + "_safe_str");
+ Val = CG.emitStringNullGuard(Val);
}
return Val;
}
@@ -198,22 +194,45 @@ Value *ArrayHandler::emitArrayAccess(ArrayAccessExprAST *Expr, CodeGen &CG) {
}
void ArrayHandler::emitArrayAssign(ArrayAssignStmtAST *Stmt, CodeGen &CG) {
- std::string Name = Stmt->getName();
- std::vector<Value*> Indices;
- if (!emitCheckedIndices(Name, Stmt->getIndices(), Stmt->getLine(), true, CG, Indices))
- return;
+ std::string ElemTypeName;
+ Value *ElemPtr = emitElementAddress(Stmt->getName(), Stmt->getIndices(),
+ Stmt->getLine(), CG, ElemTypeName);
+ if (!ElemPtr) return;
- const ArrayMetadata *Meta = getMetadata(Name);
- const TypeInfo *ElemInfo = Types.resolve(Meta->ElementTypeName);
Value *Val = CG.emitExpr(Stmt->getExpr());
- Val = CG.coerceValueToType(Val, ElemInfo);
+ Val = CG.coerceValueToType(Val, Types.resolve(ElemTypeName));
if (!Val) return;
+ Builder->CreateStore(Val, ElemPtr);
+}
+
+Value *ArrayHandler::emitElementAddress(const std::string &Name,
+ const std::vector<std::unique_ptr<ExprAST>> &IndexExprs,
+ int Line,
+ CodeGen &CG,
+ std::string &ElemTypeNameOut) {
+ std::vector<Value*> Indices;
+ if (!emitCheckedIndices(Name, IndexExprs, Line, true, CG, Indices))
+ return nullptr;
+
Value *Offset = computeFlatIndex(Name, Indices);
Value *ElemPtr = getElementPointer(Name, Offset);
- if (!ElemPtr) return;
+ if (!ElemPtr) return nullptr;
- Builder->CreateStore(Val, ElemPtr);
+ ElemTypeNameOut = getMetadata(Name)->ElementTypeName;
+ return ElemPtr;
+}
+
+Value *ArrayHandler::emitElementAddress(ArrayAccessExprAST *Expr,
+ CodeGen &CG,
+ std::string &ElemTypeNameOut) {
+ return emitElementAddress(Expr->getName(), Expr->getIndices(), Expr->getLine(),
+ CG, ElemTypeNameOut);
+}
+
+std::map<std::string, ArrayMetadata> ArrayHandler::exchangeTable(std::map<std::string, ArrayMetadata> NewTable) {
+ std::swap(ArrayTable, NewTable);
+ return NewTable;
}
bool ArrayHandler::tryEmitArrayOutput(ExprAST *Expr, CodeGen &CG) {
diff --git a/lib/CodeGen/CodeGen.cc b/lib/CodeGen/CodeGen.cc
index ae82914..4b9ebfb 100644
--- a/lib/CodeGen/CodeGen.cc
+++ b/lib/CodeGen/CodeGen.cc
@@ -363,6 +363,14 @@ void CodeGen::emitDeclareStmt(DeclareStmtAST *Stmt) {
registerSymbol(Stmt->getName(), Alloca, Info->Name, false);
}
+Value *CodeGen::emitStringNullGuard(Value *StrVal) {
+ if (!StrVal || !StrVal->getType()->isPointerTy()) return StrVal;
+ Value *IsNull = Builder->CreateICmpEQ(StrVal,
+ ConstantPointerNull::get(cast<PointerType>(StrVal->getType())),
+ "str_is_null");
+ return Builder->CreateSelect(IsNull, EmptyStringStr, StrVal, "safe_str");
+}
+
void CodeGen::emitOutputValue(Value *Val, const TypeInfo *Info, bool AppendNewline) {
if (!Val || !Info) return;
if (!Info->Printable && Info->Kind == TypeKind::Custom) {
@@ -387,13 +395,7 @@ void CodeGen::emitOutputValue(Value *Val, const TypeInfo *Info, bool AppendNewli
Args.push_back(Fmt);
Args.push_back(Builder->CreateSelect(BoolVal, TrueStr, FalseStr));
} else if (Info->isString()) {
- Value *StrVal = Val;
- if (StrVal->getType()->isPointerTy()) {
- Value *IsNull = Builder->CreateICmpEQ(StrVal,
- ConstantPointerNull::get(cast<PointerType>(StrVal->getType())),
- "str_is_null");
- StrVal = Builder->CreateSelect(IsNull, EmptyStringStr, StrVal, "safe_str");
- }
+ Value *StrVal = emitStringNullGuard(Val);
Fmt = AppendNewline
? PrintfStringFormatStr
: Builder->CreateGlobalStringPtr("%s", "fmt_str_inline", 0, TheModule.get());
@@ -491,10 +493,7 @@ Value *CodeGen::emitExpr(ExprAST *Expr) {
Value *Loaded = Builder->CreateLoad(TypeInfo->LLVMType, Info->Storage, Var->getName().c_str());
if (TypeInfo->isString()) {
- Value *IsNull = Builder->CreateICmpEQ(Loaded,
- ConstantPointerNull::get(cast<PointerType>(Loaded->getType())),
- "str_is_null");
- Loaded = Builder->CreateSelect(IsNull, EmptyStringStr, Loaded, "safe_var_str");
+ Loaded = emitStringNullGuard(Loaded);
}
return Loaded;
}
@@ -836,11 +835,15 @@ void CodeGen::emitStmt(StmtAST *Stmt) {
if (auto *FuncDef = dynamic_cast<FunctionDefAST*>(Stmt)) {
BasicBlock *SavedBlock = Builder->GetInsertBlock();
+ // Function bodies get a fresh array scope (metadata SSA values belong
+ // to the emitting function), mirroring FunctionGen's Symbols handling.
+ auto SavedArrays = Arrays->exchangeTable({});
FuncGen->emitFunctionDef(FuncDef, [this](StmtAST *S) {
this->emitStmt(S);
});
+ Arrays->exchangeTable(std::move(SavedArrays));
if (SavedBlock) Builder->SetInsertPoint(SavedBlock);
return;
}
diff --git a/lib/CodeGen/TypeSystem.cc b/lib/CodeGen/TypeSystem.cc
index 59dcc18..830ce25 100644
--- a/lib/CodeGen/TypeSystem.cc
+++ b/lib/CodeGen/TypeSystem.cc
@@ -129,6 +129,10 @@ uint64_t TypeSystem::getElementSize(const std::string &TypeName) const {
return Info ? Info->ElementSize : 0;
}
+Constant *TypeSystem::getSizeOfConstant(Type *Ty) const {
+ return ConstantExpr::getSizeOf(Ty);
+}
+
Constant *TypeSystem::getZeroValue(const std::string &TypeName) const {
const TypeInfo *Info = resolve(TypeName);
if (!Info || !Info->LLVMType || Info->LLVMType->isVoidTy()) {