Finish global high dim

main
Odeinjul 11 months ago
parent de51429073
commit a29f560cc6
No known key found for this signature in database
GPG Key ID: E384228B2B38FFBB

@ -0,0 +1,7 @@
int a[5][2] = {1,{2,3},{4},{5,6,7}};
int b[5][2] = {{1,0},{2,3},{4,0},{5,6},{7,0}};
int main(){
int i = a[3][1];
int j = b[3][1];
return (i-j);
}

@ -0,0 +1,7 @@
int main(){
int a[5][2] = {1,{2,3},{4},{5,6,7}};
int b[5][2] = {{1,0},{2,3},{4,0},{5,6},{7,0}};
int i = a[3][1];
int j = b[3][1];
return i - j;
}

@ -105,7 +105,6 @@ struct Node
struct InitVal: Node{
bool isExp;
PtrVec<InitVal> elementList;
//std::vector<Ptr<InitVal>> elementList;
Ptr<Expr> expr;
void accept(Visitor &visitor) final;
};

@ -13,6 +13,8 @@ class GlobalVariable : public User
{
private:
bool is_const_ ;
bool is_array_ ;
Ptr<std::vector<int>> array_dim_;
Ptr<Constant> init_val_;
explicit GlobalVariable(std::string name, Ptr<Module> m, Ptr<Type> ty, bool is_const, Ptr<Constant> init_val = nullptr);
void init(std::string name, Ptr<Module> m, Ptr<Type> ty, bool is_const, Ptr<Constant> init_val = nullptr);
@ -22,6 +24,15 @@ public:
Ptr<Constant> get_init() { return init_val_; }
bool is_const() { return is_const_; }
bool is_array() { return is_array_; }
void set_array(Ptr<std::vector<int>> array_dim) {
is_array_ = true;
array_dim_ = array_dim;
}
Ptr<std::vector<int>> get_array_dim() {
if (is_array_) return array_dim_;
else return nullptr;
}
std::string print();
};

@ -344,12 +344,22 @@ class AllocaInst : public Instruction
private:
explicit AllocaInst(Ptr<Type> ty, Ptr<BasicBlock> bb);
void init(Ptr<Type> ty, Ptr<BasicBlock> bb);
bool is_array_ ;
Ptr<std::vector<int>> array_dim_;
public:
static Ptr<AllocaInst> create_alloca(Ptr<Type> ty, Ptr<BasicBlock> bb);
Ptr<Type> get_alloca_type() const;
bool is_array() { return is_array_; }
void set_array(Ptr<std::vector<int>> array_dim) {
is_array_ = true;
array_dim_ = array_dim;
}
Ptr<std::vector<int>> get_array_dim() {
if (is_array_) return array_dim_;
else return nullptr;
}
virtual std::string print() override;
private:

@ -75,6 +75,8 @@ private:
class IRBuilder: public SyntaxTree::Visitor
{
private:
void ArrayInitTraverser(Ptr <SyntaxTree::InitVal> initVal, int depth, int index, Ptr<Type> varType, std::vector<int> arrayDim);
void GetArrayInit(Ptr <SyntaxTree::InitVal> initVal, std::vector<int> arrayDim, Ptr <Type> varType, bool global);
void TypeConvert(Ptr<Value> origin, Ptr<Type> expected);
void BinaryExprGen(Ptr<Value> lhs, Ptr<Value> rhs, SyntaxTree::BinOp op);
void BinaryCondExprGen(Ptr<Value> lhs, Ptr<Value> rhs, SyntaxTree::BinaryCondOp op);

@ -1,4 +1,3 @@
#include <cassert>
#include "IRBuilder.h"
namespace SysYF
@ -27,6 +26,8 @@ Ptr<BasicBlock> retBB;
Ptr<Value> retAlloca;
Ptr<Value> tmpInst;
Ptr<ConstantArray> arrayInitializer;
Ptr<std::vector<Ptr<Constant>>> constArrayInit;
// types
@ -37,6 +38,70 @@ Ptr<Type> FLOAT_T;
Ptr<Type> INT32PTR_T;
Ptr<Type> FLOATPTR_T;
void IRBuilder::ArrayInitTraverser(Ptr <SyntaxTree::InitVal> initVal, int depth, int index, Ptr<Type> varType, std::vector<int> arrayDim) {
if(initVal->isExp) {
initVal->expr->accept(*this);
TypeConvert(tmpInst, varType);
//set constArrayInit[index] = tmpInst
constArrayInit->at(index) = dynamic_pointer_cast<Constant>(tmpInst);
} else {
for (int i = 0; i < initVal->elementList.size(); i++) {
auto tmpIndex = 1;
for (int j = depth + 1; j < arrayDim.size(); j++) {
tmpIndex *= arrayDim[j];
}
ArrayInitTraverser(initVal->elementList[i], depth + 1, index + i * tmpIndex, varType, arrayDim);
}
}
}
void IRBuilder::GetArrayInit(Ptr <SyntaxTree::InitVal> initVal, std::vector<int> arrayDim, Ptr <Type> varType, bool global = true) {
/*
arrayInitializer.reset();
// 一维数组
std::vector<Ptr<Constant>> varInit;
for(auto initValPtr : initVal->elementList){
initValPtr->expr->accept(*this);
TypeConvert(tmpInst, varType);
varInit.push_back(dynamic_pointer_cast<Constant>(tmpInst));
}
auto arrayLen = arrayDim[0];
auto otherLen = arrayLen - initVal->elementList.size();
auto tmpZero = CONST_INT(0);
TypeConvert(tmpZero, varType);
for (auto i = 0u; i < otherLen; i++) {
varInit.push_back(dynamic_pointer_cast<Constant>(tmpInst));
}
auto arrayType = varType->get_array_type(varType, arrayLen);
arrayInitializer = ConstantArray::create(arrayType, varInit);
*/
auto arraySize = 1;
for(auto i : arrayDim){
arraySize *= i;
}
constArrayInit = std::make_shared<std::vector<Ptr<Constant>>>(arraySize);
ArrayInitTraverser(initVal, 0, 0, varType, arrayDim);
auto arrayType = varType->get_array_type(varType, arraySize);
//iterate constArrayInit to get arrayInitializer
std::vector<Ptr<Constant>> varInit;
for(auto i : *constArrayInit){
if (i == nullptr) {
Ptr<Constant> tmpZero;
if(varType == INT32_T){
tmpZero = CONST_INT(0);
} else{
tmpZero = CONST_FLOAT(0.0);
}
TypeConvert(tmpZero, varType);
varInit.push_back(dynamic_pointer_cast<Constant>(tmpInst));
} else {
varInit.push_back(i);
}
}
arrayInitializer = ConstantArray::create(arrayType, varInit);
}
Ptr<Type> GetBaseType(SyntaxTree::Type type){
switch(type){
case SyntaxTree::Type::INT:
@ -62,6 +127,8 @@ Ptr<Type> GetParamType(SyntaxTree::Type type, bool isPtr = false){
else if(tmpType == FLOAT_T){
return FLOATPTR_T;
}
else
return nullptr;
}
}
@ -107,8 +174,7 @@ void IRBuilder::BinaryExprGen(Ptr<Value> lhs, Ptr<Value> rhs, SyntaxTree::BinOp
}
break;
case SyntaxTree::BinOp::MODULO:
if (isFloat) { ;// not support
} else {
if (!isFloat) {
tmpInst = CONST_INT(lInt % rInt);
}
break;
@ -446,11 +512,23 @@ void IRBuilder::visit(SyntaxTree::FuncParam &node) {
void IRBuilder::visit(SyntaxTree::VarDef &node) {
// type
auto varType = GetBaseType(node.btype);
std::vector<int> arrayDim;
Ptr<ArrayType> arrayType;
int arraySize = 1;
if (!node.array_length.empty()) {
node.array_length[0]->accept(*this);
auto constInt = dynamic_pointer_cast<ConstantInt>(tmpInst);
arrayType = ArrayType::create(varType, constInt->get_value());
for (int i = node.array_length.size() - 1; i >= 0; i--) {
node.array_length[i]->accept(*this);
auto constInt = dynamic_pointer_cast<ConstantInt>(tmpInst);
if(i == node.array_length.size() - 1) {
arraySize = constInt->get_value();
arrayDim.push_back(constInt->get_value());
} else {
arraySize *= constInt->get_value();
arrayDim.push_back(constInt->get_value());
}
}
arrayType = ArrayType::create(varType, arraySize);
std::reverse(arrayDim.begin(), arrayDim.end());
}
Ptr<Value> identAlloca;
@ -461,25 +539,21 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) {
identAlloca = GlobalVariable::create(node.name, module, varType, false, zeroInit);
} else {
identAlloca = GlobalVariable::create(node.name, module, arrayType, false, zeroInit);
//
auto tmpIdent = dynamic_pointer_cast<GlobalVariable>(identAlloca);
tmpIdent->set_array(std::make_shared<std::vector<int>>(arrayDim));
identAlloca = dynamic_pointer_cast<Value>(tmpIdent);
//
}
} else {
if (!node.array_length.empty()) {
std::vector<Ptr<Constant>> varInit;
for (const auto &init : node.initializers->elementList) {
init->accept(*this);
TypeConvert(tmpInst, varType);
varInit.push_back(dynamic_pointer_cast<Constant>(tmpInst));
}
auto arrayLen = arrayType->get_num_of_elements();
auto otherLen = arrayLen - node.initializers->elementList.size();
auto tmpZero = CONST_INT(0);
TypeConvert(tmpZero, varType);
for (int i = 0; i < otherLen; i++) {
varInit.push_back(dynamic_pointer_cast<Constant>(tmpInst));
}
auto arrayInit = ConstantArray::create(varType->get_array_type(varType, arrayLen), varInit);
identAlloca = GlobalVariable::create(node.name, module, arrayType, node.is_constant, arrayInit);
GetArrayInit(node.initializers, arrayDim, varType);
identAlloca = GlobalVariable::create(node.name, module, arrayType, node.is_constant, arrayInitializer);
//
auto tmpIdent = dynamic_pointer_cast<GlobalVariable>(identAlloca);
tmpIdent->set_array(std::make_shared<std::vector<int>>(arrayDim));
identAlloca = dynamic_pointer_cast<Value>(tmpIdent);
//
} else {
if (node.is_constant) {
node.initializers->expr->accept(*this);
@ -501,7 +575,6 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) {
node.initializers->expr->accept(*this);
TypeConvert(tmpInst, varType);
scope.push(node.name, tmpInst);
//builder->create_store(tmpInst, identAlloca);
} else {
if (node.array_length.empty()) {
identAlloca = builder->create_alloca(varType);
@ -513,25 +586,19 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) {
}
return ;
} else {
std::vector<Ptr<Constant>> varInit;
for (const auto &init : node.initializers->elementList) {
init->accept(*this);
TypeConvert(tmpInst, varType);
varInit.push_back(dynamic_pointer_cast<Constant>(tmpInst));
}
auto otherLen = arrayType->get_num_of_elements() - node.initializers->elementList.size();
auto tmpZero = CONST_INT(0);
TypeConvert(tmpZero, varType);
for (int i = 0; i < otherLen; i++) {
varInit.push_back(dynamic_pointer_cast<Constant>(tmpInst));
}
auto zeroInit = ConstantZero::create(varType, module);
GetArrayInit(node.initializers, arrayDim, varType);
//
identAlloca = builder->create_alloca(arrayType);
auto tmpIdent = dynamic_pointer_cast<AllocaInst>(identAlloca);
tmpIdent->set_array(std::make_shared<std::vector<int>>(arrayDim));
//
identAlloca = dynamic_pointer_cast<Value>(tmpIdent);
scope.push(node.name, identAlloca);
for (int i = 0; i < varInit.size(); i++) {
auto varInit = constArrayInit.get();
for (int i = 0u; i < arraySize; i++) {
auto index = CONST_INT(i);
auto ptr = builder->create_gep(identAlloca, {CONST_INT(0), index});
builder->create_store(varInit[i], ptr);
builder->create_store((*varInit)[i], ptr);
}
}
}
@ -542,7 +609,8 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) {
void IRBuilder::visit(SyntaxTree::LVal &node) {
auto ident = scope.find(node.name, false);
if (!node.array_index.empty()) {
node.array_index[0]->accept(*this);
/*node.array_index[0]->accept(*this);
auto constIndex = dynamic_pointer_cast<ConstantInt>(tmpInst);
auto globalIdent = dynamic_pointer_cast<GlobalVariable>(ident);
if(globalIdent != nullptr && globalIdent->is_const() && constIndex != nullptr) {
@ -551,6 +619,37 @@ void IRBuilder::visit(SyntaxTree::LVal &node) {
} else {
tmpInst = builder->create_gep(ident, {CONST_INT(0), tmpInst});
}
*/
int index = 0;
auto globalIdent = dynamic_pointer_cast<GlobalVariable>(ident);
auto localIdent = dynamic_pointer_cast<AllocaInst>(ident);
Ptr<std::vector<int>> arrayDimPtr;
if (globalIdent != nullptr) {
arrayDimPtr = globalIdent->get_array_dim();
} else if (localIdent != nullptr) {
arrayDimPtr = localIdent->get_array_dim();
}
bool index_is_constant = true;
for (int i = 0; i < node.array_index.size(); i++) {
node.array_index[i]->accept(*this);
auto constIndex = dynamic_pointer_cast<ConstantInt>(tmpInst);
if(constIndex == nullptr) {
index_is_constant = false;
}
int tmpIndex = 1;
for (int j = i + 1; j < node.array_index.size(); j++) {
tmpIndex *= (*arrayDimPtr)[j];
}
index += constIndex->get_value() * tmpIndex;
}
if(globalIdent != nullptr && globalIdent->is_const() && index_is_constant) {
auto arrayInit = dynamic_pointer_cast<ConstantArray>(globalIdent->get_init());
tmpInst = arrayInit->get_element_value(index);
} else {
tmpInst = builder->create_gep(ident, {CONST_INT(0), CONST_INT(index)});
}
}
else {
if (ident->get_type()->is_pointer_type() && ident->get_type()->get_pointer_element_type()->is_array_type()) {
@ -559,7 +658,6 @@ void IRBuilder::visit(SyntaxTree::LVal &node) {
tmpInst = ident;
}
}
return ;
}
// FINISH
@ -599,7 +697,6 @@ void IRBuilder::visit(SyntaxTree::ReturnStmt &node) {
}
// every ret stmt only store the value and jump to the retBB
builder->create_br(retBB);
return ;
}
// Finish
@ -611,18 +708,15 @@ void IRBuilder::visit(SyntaxTree::BlockStmt &node) {
stmt->accept(*this);
}
scope.exit();
return ;
}
// FINISH
void IRBuilder::visit(SyntaxTree::EmptyStmt &node) {
return ;
}
// FINISH
void IRBuilder::visit(SyntaxTree::ExprStmt &node) {
node.exp->accept(*this);
return ;
}
// FINISH
@ -636,7 +730,6 @@ void IRBuilder::visit(SyntaxTree::UnaryCondExpr &node) {
} else {
tmpInst = CONST_INT((constInt->get_value() == 0 || constFloat->get_value() == 0 ) ? 1 : 0);
}
return ;
}
@ -790,19 +883,16 @@ void IRBuilder::visit(SyntaxTree::WhileStmt &node) {
builder->set_insert_point(afterBB);
curWhileBlock = tmpWhileBlock;
return ;
}
//FINISH
void IRBuilder::visit(SyntaxTree::BreakStmt &node) {
builder->create_br(curWhileBlock.afterBB);
return ;
}
//FINISH
void IRBuilder::visit(SyntaxTree::ContinueStmt &node) {
builder->create_br(curWhileBlock.condBB);
return ;
}
}
}
Loading…
Cancel
Save