diff options
Diffstat (limited to 'lib/CodeGen/ArrayHandler.cc')
| -rw-r--r-- | lib/CodeGen/ArrayHandler.cc | 193 |
1 files changed, 0 insertions, 193 deletions
diff --git a/lib/CodeGen/ArrayHandler.cc b/lib/CodeGen/ArrayHandler.cc index bd68473..6a89781 100644 --- a/lib/CodeGen/ArrayHandler.cc +++ b/lib/CodeGen/ArrayHandler.cc @@ -253,196 +253,3 @@ std::map<std::string, ArrayMetadata> ArrayHandler::exchangeTable(std::map<std::s std::swap(ArrayTable, NewTable); return NewTable; } - -void ArrayHandler::bindArrayParameter(const std::string &Name, - const std::string &ElemTypeName, - Value *DataPtr, - const std::vector<Value*> &LBs, - const std::vector<Value*> &UBs, - bool MakeCopy, - CodeGen &CG) { - const TypeInfo *ElemInfo = Types.resolve(ElemTypeName); - if (!ElemInfo || !ElemInfo->LLVMType || ElemInfo->isVoid()) { - CG.reportError("Unknown array element type %s", ElemTypeName.c_str()); - return; - } - - std::vector<Value*> Multipliers; - Value *TotalElements = nullptr; - computeDimsAndMultipliers(Name, LBs, UBs, Multipliers, TotalElements); - - ArrayMetadata Meta; - Meta.Rank = static_cast<int>(LBs.size()); - Meta.ElementTypeName = ElemInfo->Name; - Meta.ElementType = ElemInfo->LLVMType; - Meta.ElementSizeC = Types.getSizeOfConstant(ElemInfo->LLVMType); - Meta.LowerBounds = LBs; - Meta.UpperBounds = UBs; - Meta.Multipliers = std::move(Multipliers); - ArrayTable[Name] = Meta; - - Value *Ptr = DataPtr; - if (MakeCopy) { - // BYVAL: whole-buffer copy so callee writes stay invisible to the - // caller. The copy is malloc'd and never freed, consistent with the - // project-wide string policy. - Value *TotalBytes = Builder->CreateMul(TotalElements, Meta.ElementSizeC, - Name + "_copy_bytes"); - Value *Copy = Builder->CreateCall(MallocFunc, TotalBytes, Name + "_copy"); - FunctionType *MemcpyType = FunctionType::get( - PointerType::getUnqual(*TheContext), - {PointerType::getUnqual(*TheContext), PointerType::getUnqual(*TheContext), - Type::getInt64Ty(*TheContext)}, - false); - FunctionCallee MemcpyFunc = TheModule->getOrInsertFunction("memcpy", MemcpyType); - Builder->CreateCall(MemcpyFunc, {Copy, DataPtr, TotalBytes}); - Ptr = Copy; - } - - Function *TheFunction = Builder->GetInsertBlock()->getParent(); - AllocaInst *Alloca = CG.CreateEntryBlockAlloca(TheFunction, PointerType::getUnqual(*TheContext), Name); - Builder->CreateStore(Ptr, Alloca); - - CG.registerSymbol(Name, Alloca, ElemInfo->Name, true); -} - -bool ArrayHandler::emitArrayArgument(ExprAST *ArgExpr, - const std::string &ElemTypeName, - int Rank, - const std::vector<std::pair<int64_t, int64_t>> &DeclaredBounds, - const std::string &Callee, - int Line, - CodeGen &CG, - std::vector<Value*> &Out) { - auto *Var = dynamic_cast<VariableExprAST*>(ArgExpr); - const ArrayMetadata *Meta = Var ? getMetadata(Var->getName()) : nullptr; - if (!Meta) { - CG.reportError("Argument to %s must be a whole array variable (ARRAY OF %s)", - Callee.c_str(), ElemTypeName.c_str()); - return false; - } - if (!CG.resolveType(Meta->ElementTypeName)->sameType(CG.resolveType(ElemTypeName))) { - CG.reportError("Array argument %s to %s must have element type %s (got %s)", - Var->getName().c_str(), Callee.c_str(), - ElemTypeName.c_str(), Meta->ElementTypeName.c_str()); - return false; - } - if (Meta->Rank != Rank) { - CG.reportError("Array argument %s to %s must have %d dimension%s (got %d)", - Var->getName().c_str(), Callee.c_str(), - Rank, Rank == 1 ? "" : "s", Meta->Rank); - return false; - } - - // Bounded parameters are a contract: verified at compile time when the - // caller's bounds are constants (the common case), at run time otherwise. - for (size_t D = 0; D < DeclaredBounds.size(); ++D) { - int64_t DeclLo = DeclaredBounds[D].first; - int64_t DeclHi = DeclaredBounds[D].second; - auto *ActLo = dyn_cast<ConstantInt>(Meta->LowerBounds[D]); - auto *ActHi = dyn_cast<ConstantInt>(Meta->UpperBounds[D]); - if (ActLo && ActHi) { - if (ActLo->getSExtValue() != DeclLo || ActHi->getSExtValue() != DeclHi) { - CG.reportError("Array argument %s to %s has bounds [%lld:%lld] but the parameter declares [%lld:%lld]", - Var->getName().c_str(), Callee.c_str(), - static_cast<long long>(ActLo->getSExtValue()), - static_cast<long long>(ActHi->getSExtValue()), - static_cast<long long>(DeclLo), - static_cast<long long>(DeclHi)); - return false; - } - } else { - RuntimeChecker.emitArrayArgBoundsCheck(Meta->LowerBounds[D], Meta->UpperBounds[D], - DeclLo, DeclHi, Line); - } - } - - Value *DataPtr = getArrayBasePointer(Var->getName()); - if (!DataPtr) return false; - Out.push_back(DataPtr); - for (int D = 0; D < Rank; ++D) { - Out.push_back(Meta->LowerBounds[D]); - Out.push_back(Meta->UpperBounds[D]); - } - return true; -} - -bool ArrayHandler::tryEmitArrayOutput(ExprAST *Expr, CodeGen &CG) { - std::string Name; - const std::vector<std::unique_ptr<ExprAST>> *IndexExprs = nullptr; - int Line = 0; - - if (auto *Var = dynamic_cast<VariableExprAST*>(Expr)) { - Name = Var->getName(); - if (!getMetadata(Name)) return false; - } else if (auto *Acc = dynamic_cast<ArrayAccessExprAST*>(Expr)) { - Name = Acc->getName(); - const ArrayMetadata *Meta = getMetadata(Name); - if (!Meta) return false; - if (Acc->getIndices().size() == static_cast<size_t>(Meta->Rank)) { - return false; // full element access: handled by the normal expression path - } - IndexExprs = &Acc->getIndices(); - Line = Acc->getLine(); - } else { - return false; - } - - const TypeInfo *ElemInfo = Types.resolve(getMetadata(Name)->ElementTypeName); - if (ElemInfo && !ElemInfo->isOutputtable()) { - CG.reportError("Cannot OUTPUT array %s of type %s; output individual fields", - Name.c_str(), ElemInfo->Name.c_str()); - return true; // diagnosed - } - - std::vector<Value*> Indices; - if (IndexExprs && !emitCheckedIndices(Name, *IndexExprs, Line, false, CG, Indices)) { - return true; // diagnosed - } - - emitPrintLoop(Name, static_cast<int>(Indices.size()), Indices, CG); - return true; -} - -void ArrayHandler::emitPrintLoop(const std::string &Name, - int CurrentDim, - std::vector<Value*> CurrentIndices, - CodeGen &CG) { - const ArrayMetadata *Meta = getMetadata(Name); - if (!Meta) return; - - if (CurrentDim == Meta->Rank) { - Value *Offset = computeFlatIndex(Name, CurrentIndices); - Value *Val = loadElement(Name, Offset, CG); - if (!Val) return; - - CG.emitOutputValue(Val, Types.resolve(Meta->ElementTypeName), true); - return; - } - - Function *TheFunction = Builder->GetInsertBlock()->getParent(); - BasicBlock *LoopBB = BasicBlock::Create(*TheContext, "arr_loop", TheFunction); - BasicBlock *AfterBB = BasicBlock::Create(*TheContext, "arr_after", TheFunction); - - AllocaInst *LoopVar = CG.CreateEntryBlockAlloca(TheFunction, Type::getInt64Ty(*TheContext), "idx"); - Value *Start = Meta->LowerBounds[CurrentDim]; - Value *End = Meta->UpperBounds[CurrentDim]; - - Builder->CreateStore(Start, LoopVar); - Builder->CreateBr(LoopBB); - - Builder->SetInsertPoint(LoopBB); - Value *CurVal = Builder->CreateLoad(Type::getInt64Ty(*TheContext), LoopVar); - - std::vector<Value*> NextIndices = CurrentIndices; - NextIndices.push_back(CurVal); - emitPrintLoop(Name, CurrentDim + 1, NextIndices, CG); - - Value *NextVal = Builder->CreateAdd(CurVal, ConstantInt::get(*TheContext, APInt(64, 1))); - Builder->CreateStore(NextVal, LoopVar); - - Value *Cond = Builder->CreateICmpSLE(NextVal, End); - Builder->CreateCondBr(Cond, LoopBB, AfterBB); - - Builder->SetInsertPoint(AfterBB); -} |
