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{ struct InitVal: Node{
bool isExp; bool isExp;
PtrVec<InitVal> elementList; PtrVec<InitVal> elementList;
//std::vector<Ptr<InitVal>> elementList;
Ptr<Expr> expr; Ptr<Expr> expr;
void accept(Visitor &visitor) final; void accept(Visitor &visitor) final;
}; };

@ -13,6 +13,8 @@ class GlobalVariable : public User
{ {
private: private:
bool is_const_ ; bool is_const_ ;
bool is_array_ ;
Ptr<std::vector<int>> array_dim_;
Ptr<Constant> init_val_; Ptr<Constant> init_val_;
explicit GlobalVariable(std::string name, Ptr<Module> m, Ptr<Type> ty, bool is_const, Ptr<Constant> init_val = nullptr); 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); 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_; } Ptr<Constant> get_init() { return init_val_; }
bool is_const() { return is_const_; } 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(); std::string print();
}; };

@ -344,12 +344,22 @@ class AllocaInst : public Instruction
private: private:
explicit AllocaInst(Ptr<Type> ty, Ptr<BasicBlock> bb); explicit AllocaInst(Ptr<Type> ty, Ptr<BasicBlock> bb);
void init(Ptr<Type> ty, Ptr<BasicBlock> bb); void init(Ptr<Type> ty, Ptr<BasicBlock> bb);
bool is_array_ ;
Ptr<std::vector<int>> array_dim_;
public: public:
static Ptr<AllocaInst> create_alloca(Ptr<Type> ty, Ptr<BasicBlock> bb); static Ptr<AllocaInst> create_alloca(Ptr<Type> ty, Ptr<BasicBlock> bb);
Ptr<Type> get_alloca_type() const; 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; virtual std::string print() override;
private: private:

@ -75,6 +75,8 @@ private:
class IRBuilder: public SyntaxTree::Visitor class IRBuilder: public SyntaxTree::Visitor
{ {
private: 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 TypeConvert(Ptr<Value> origin, Ptr<Type> expected);
void BinaryExprGen(Ptr<Value> lhs, Ptr<Value> rhs, SyntaxTree::BinOp op); void BinaryExprGen(Ptr<Value> lhs, Ptr<Value> rhs, SyntaxTree::BinOp op);
void BinaryCondExprGen(Ptr<Value> lhs, Ptr<Value> rhs, SyntaxTree::BinaryCondOp op); void BinaryCondExprGen(Ptr<Value> lhs, Ptr<Value> rhs, SyntaxTree::BinaryCondOp op);

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