From ba4883c186b7da59ce6bb9c8a8ec3dae12807ab9 Mon Sep 17 00:00:00 2001 From: Alfred Huang Date: Tue, 23 Feb 2021 17:44:39 -0800 Subject: [PATCH] Merge in C LowerArray --- src/mapleall/maple_be/include/be/lower.h | 1 + src/mapleall/maple_be/src/be/lower.cpp | 161 ++++++++++++++++++++++- 2 files changed, 161 insertions(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/include/be/lower.h b/src/mapleall/maple_be/include/be/lower.h index 07393dde48..183bd4777a 100644 --- a/src/mapleall/maple_be/include/be/lower.h +++ b/src/mapleall/maple_be/include/be/lower.h @@ -134,6 +134,7 @@ class CGLowerer { BaseNode *LowerArrayDim(ArrayNode &array, int32 dim); BaseNode *LowerArrayForLazyBiding(BaseNode &baseNode, BaseNode &offsetNode, const BaseNode &parent); BaseNode *LowerArray(ArrayNode &array, const BaseNode &parent); + BaseNode *LowerCArray(ArrayNode &array); DassignNode *SaveReturnValueInLocal(StIdx, uint16); void LowerCallStmt(StmtNode&, StmtNode*&, BlockNode&, MIRType *retTy = nullptr); diff --git a/src/mapleall/maple_be/src/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index 2aa8bf469c..4912e1486f 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -375,6 +375,161 @@ BaseNode *CGLowerer::LowerArray(ArrayNode &array, const BaseNode &parent) { return rAdd; } +BaseNode *CGLowerer::LowerCArray(ArrayNode &array) { + MIRType *aType = array.GetArrayType(GlobalTables::GetTypeTable()); + if (aType->GetKind() == kTypeFArray || aType->GetKind() == kTypeJArray) { + return LowerFarray(array); + } + + MIRArrayType *arrayType = static_cast(aType); + /* There are two cases where dimension > 1. + * 1) arrayType->dim > 1. Process the current arrayType. (nestedArray = false) + * 2) arrayType->dim == 1, but arraytype->eTyIdx is another array. (nestedArray = true) + * Assume at this time 1) and 2) cannot mix. + * Along with the array dimension, there is the array indexing. + * It is allowed to index arrays less than the dimension. + * This is dictated by the number of indexes. + */ + bool nestedArray = false; + int dim = arrayType->GetDim(); + MIRType *innerType = nullptr; + MIRArrayType *innerArrayType = nullptr; + uint32 elemSize = 0; + if (dim == 1) { + innerType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(arrayType->GetElemTyIdx()); + if (innerType->GetKind() == kTypeArray) { + nestedArray = true; + do { + innerArrayType = static_cast(innerType); + elemSize = RoundUp(beCommon.GetTypeSize(innerArrayType->GetElemTyIdx().GetIdx()), + beCommon.GetTypeAlign(arrayType->GetElemTyIdx().GetIdx())); + dim++; + innerType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(innerArrayType->GetElemTyIdx()); + } while (innerType->GetKind() == kTypeArray); + } + } + + int32 numIndex = array.NumOpnds() - 1; + MIRArrayType *curArrayType = arrayType; + BaseNode *resNode = NodeConvert(array.GetPrimType(), *array.GetIndex(0)); + if (dim > 1) { + BaseNode *prevNode = nullptr; + for (int i = 0; (i < dim) && (i < numIndex); i++) { + uint32 mpyDim = 1; + if (nestedArray) { + CHECK_FATAL(arrayType->GetSizeArrayItem(0) > 0, "Zero size array dimension"); + innerType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(curArrayType->GetElemTyIdx()); + curArrayType = static_cast(innerType); + while (innerType->GetKind() == kTypeArray) { + innerArrayType = static_cast(innerType); + mpyDim *= innerArrayType->GetSizeArrayItem(0); + innerType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(innerArrayType->GetElemTyIdx()); + } + } else { + CHECK_FATAL(arrayType->GetSizeArrayItem(i) > 0, "Zero size array dimension"); + for (int j = i + 1; j < dim; j++) { + mpyDim *= arrayType->GetSizeArrayItem(j); + } + } + + BaseNode *index = static_cast(array.GetIndex(i)); + bool isConst = false; + int32 indexVal = 0; + if (index->op == OP_constval) { + ConstvalNode *constNode = static_cast(index); + indexVal = (static_cast(constNode->GetConstVal()))->GetValue(); + isConst = true; + MIRIntConst *newConstNode = mirModule.GetMemPool()->New( + indexVal * mpyDim, + *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(array.GetPrimType()))); + BaseNode *newValNode = mirModule.CurFuncCodeMemPool()->New(newConstNode); + newValNode->SetPrimType(array.GetPrimType()); + if (i == 0) { + prevNode = newValNode; + continue; + } else { + resNode = newValNode; + } + } + if (i > 0 && isConst == false) { + resNode = NodeConvert(array.GetPrimType(), *array.GetIndex(i)); + } + + BaseNode *mpyNode; + if (isConst) { + MIRIntConst *mulConst = mirModule.GetMemPool()->New( + mpyDim * indexVal, + *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(array.GetPrimType()))); + BaseNode *mulSize = mirModule.CurFuncCodeMemPool()->New(mulConst); + mulSize->SetPrimType(array.GetPrimType()); + mpyNode = mulSize; + } else if (mpyDim == 1 && prevNode) { + mpyNode = prevNode; + prevNode = resNode; + } else { + mpyNode = mirModule.CurFuncCodeMemPool()->New(OP_mul); + mpyNode->SetPrimType(array.GetPrimType()); + MIRIntConst *mulConst = mirModule.GetMemPool()->New( + mpyDim, + *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(array.GetPrimType()))); + BaseNode *mulSize = mirModule.CurFuncCodeMemPool()->New(mulConst); + mulSize->SetPrimType(array.GetPrimType()); + mpyNode->SetOpnd(NodeConvert(array.GetPrimType(), *mulSize), 0); + mpyNode->SetOpnd(resNode, 1); + } + if (i == 0) { + prevNode = mpyNode; + continue; + } + BaseNode *newResNode = mirModule.CurFuncCodeMemPool()->New(OP_add); + newResNode->SetPrimType(array.GetPrimType()); + newResNode->SetOpnd(mpyNode, 0); + newResNode->SetOpnd(prevNode, 1); + prevNode = newResNode; + } + resNode = prevNode; + } + + BaseNode *rMul = nullptr; + // esize is the size of the array element (eg. int = 4 long = 8) + uint32 esize; + if (nestedArray) { + esize = elemSize; + } else { + esize = beCommon.GetTypeSize(arrayType->GetElemTyIdx().GetIdx()); + } + Opcode opadd = OP_add; + if (resNode->op == OP_constval) { + // index is a constant, we can calculate the offset now + ConstvalNode *idxNode = static_cast(resNode); + int64 idx = static_cast(idxNode->GetConstVal())->GetValue(); + MIRIntConst *econst = mirModule.GetMemPool()->New( + idx * esize, + *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(array.GetPrimType()))); + rMul = mirModule.CurFuncCodeMemPool()->New(econst); + rMul->SetPrimType(array.GetPrimType()); + if (dim == 1 && array.GetBase()->op == OP_addrof) { + opadd = OP_CG_array_elem_add; + } + } else { + MIRIntConst *econst = mirModule.GetMemPool()->New( + esize, + *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(array.GetPrimType()))); + BaseNode *eSize = mirModule.CurFuncCodeMemPool()->New(econst); + eSize->SetPrimType(array.GetPrimType()); + rMul = mirModule.CurFuncCodeMemPool()->New(OP_mul); + rMul->SetPrimType(array.GetPrimType()); + rMul->SetOpnd(resNode, 0); + rMul->SetOpnd(eSize, 1); + } + BaseNode *baseNode = NodeConvert(array.GetPrimType(), *array.GetBase()); + BaseNode *rAdd = mirModule.CurFuncCodeMemPool()->New(opadd); + rAdd->SetPrimType(array.GetPrimType()); + rAdd->SetOpnd(baseNode, 0); + rAdd->SetOpnd(rMul, 1); + return rAdd; +} + BaseNode *CGLowerer::LowerDreadBitfield(DreadNode &dread) { MIRSymbol *symbol = mirModule.CurFunction()->GetLocalOrGlobalSymbol(dread.GetStIdx()); MIRStructType *structTy = static_cast(symbol->GetType()); @@ -1698,7 +1853,11 @@ BaseNode *CGLowerer::LowerExpr(const BaseNode &parent, BaseNode &expr, BlockNode switch (expr.GetOpCode()) { case OP_array: { ProcessArrayExpr(expr, blkNode); - return LowerArray(static_cast(expr), parent); + if (!mirModule.IsCModule()) { + return LowerArray(static_cast(expr), parent); + } else { + return LowerCArray(static_cast(expr)); + } } case OP_dread: -- Gitee