diff --git a/projects/PiLeiFX/ZenoFX/Ast.h b/projects/PiLeiFX/ZenoFX/Ast.h new file mode 100644 index 0000000000..506bf451ea --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/Ast.h @@ -0,0 +1,115 @@ +// +// Created by admin on 2022/5/6. +// + +#pragma once + +#include "Lexical.h" +#include "Location.h" +#include +#include +#include +#include +#include +#include +namespace zfx { + + enum VarType { + Symbol, + Parameter + }; + + enum Op { + + }; + class AstVisitor { + + }; + + class AstNode { + public: + Position beginPos; + Position endPos; + virtual void dump() = 0; + virtual std::any accept(AstVisitor &visitor, std::string additional = "") = 0; + virtual ~AstNode(); + }; +//语句 + class Statement: AstNode { + + }; + //声明,子类为$ @ + class Decl :public AstNode { + public: + VarType varType;//变量类型 + std::string name;//变量名称 + expilic Decl(VarType varType) : varType (varType) { + + } + }; + + class VariableDecl : public Decl { + //变量类型 + //变量初始化的形式, + public: + VarType varType; + //std::shared_ptr init;//变量初始化的语句 + explicit VariableDecl(VarType varType , const std::string& name) : Decl(varType), name(name) { + + } + std::any accept(AstVisitor& visitor) { + + } + + void dump(std::string prefix) { + + } + }; + + class Statement : public AstNode { + + }; + + class Expression:public AstNode { + public: + std::any constValue;//本表达式的常量值,用作后面的常量折叠等分析 + }; + + class ExpressionStatement : public Statement { + public: + std::shared_ptr exp; + + + }; + /* + * 二元表达式 + * */ + class Binary { + public: + Op op; + //左边表达式 + //右边表达式 + Binary() { + + } + + std::any accept(AstVisitor& visitor, const std::string &additional) { + + } + }; + + class Unary { + public: + Op op; + //表达式 + Unary() { + + } + + std::any accept(AstVisitor& visitor, const std::string &additional) { + + } + }; + +} + diff --git a/projects/PiLeiFX/ZenoFX/CodeGen.h b/projects/PiLeiFX/ZenoFX/CodeGen.h new file mode 100644 index 0000000000..3f4fb3a760 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/CodeGen.h @@ -0,0 +1,40 @@ +// +// Created by admin on 2022/5/11. +// + +#pragma once +#include +#include +/* + * This class is an interface to complete a codegen in the Statement class + * */ +namespace zfx { + Value* BinaryExprAst::codegen() { + if (op == '=') { + VariableExprAst* LHSE = static_cast<> + if (!LHSE) { + std::cout << "destination of '=' must be" << std::endl; + + } + Value* Val = RHS->codegen(); + if (!Val) { + return nullptr; + } + } + } + + static AllocaInst *createEntryBlock(Function* function, std::string& VarName) { + + } + + Value* NumberExprAst::codegen() { + + } + + Value* UnaryExprAst::codegen() { + Value* OperandV = Operand->codegen(); + if (!OperandV) { + return nullptr; + } + } +} diff --git a/projects/PiLeiFX/ZenoFX/ControlCheck.cpp b/projects/PiLeiFX/ZenoFX/ControlCheck.cpp new file mode 100644 index 0000000000..3fef3049bb --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/ControlCheck.cpp @@ -0,0 +1,24 @@ +// +// Created by admin on 2022/5/14. +// + +#include "Ast.h +#include +#include +/* + * 这里我们用了一个最简单的bool 栈来判断if else 结构语句是否匹配成功 + * + * */ +namespace zfx { + struct ControlCheck { + using visit_emit_types = std::tuple<>; + + void visit() { + + } + }; + + void apply_control_check() { + + } +} \ No newline at end of file diff --git a/projects/PiLeiFX/ZenoFX/EmitAssembler.cpp b/projects/PiLeiFX/ZenoFX/EmitAssembler.cpp new file mode 100644 index 0000000000..221e22a977 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/EmitAssembler.cpp @@ -0,0 +1,13 @@ +// +// Created by admin on 2022/5/12. +// + +#include + +namespace zfx { + struct EmitAssembly { + + std::stringstream oss; + + }; +} \ No newline at end of file diff --git a/projects/PiLeiFX/ZenoFX/Error.h b/projects/PiLeiFX/ZenoFX/Error.h new file mode 100644 index 0000000000..7257c115c8 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/Error.h @@ -0,0 +1,32 @@ +// +// Created by admin on 2022/5/30. +// +#pragma once + +#include +namespace zfx { + struct Position{ + uint32_t begin; + uint32_t end; + uint32_t line; + uint32_t col; + + Position(){} + Position(uint32_t begin, uint32_t end, uint32_t line, uint32_t col) : begin(begin), + end(end), line(line), col(col) { + + } + + Position(const Position &rhs) { + this->begin = rhs.begin; + this->end = rhs.end; + this->line = rhs.line; + this->col = rhs.col; + } + + std::string ToString() { + return "ln" + std::to_string(this->line) + ", col" + std::to_string(this->col) + + ", Pos:" + std::to_string(this->pos); + } + }; +} diff --git a/projects/PiLeiFX/ZenoFX/IR/BasicBlock.h b/projects/PiLeiFX/ZenoFX/IR/BasicBlock.h new file mode 100644 index 0000000000..793ee37943 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/IR/BasicBlock.h @@ -0,0 +1,45 @@ +// +// Created by admin on 2022/5/27. +// + +#include "Module.h" +#include +#include +#include +#include + + +namespace zfx { + class BasicBlock { + public: + static BasicBlock *create(Module *m, const std::string& name) { + + return new BasicBlock(m, name); + } + + BasicBlock(const BasicBlock& ) = delete; + BasicBlock& operator=(const BasicBlock&) = delete; + const Module* getModule() const { + + } + + Module* getModule() { + + } + + virtual std::string print() override; + + + //api for cfg + std::list &get_pre_basic_blocks() { + + } + + //选一个迭代器遍历一遍 + private: + explicit BasicBlock(Module *m, const std::string &name); + std::list pre_bbs; + std::list succ_bbs; + + }; +} diff --git a/projects/PiLeiFX/ZenoFX/IR/IR.cpp b/projects/PiLeiFX/ZenoFX/IR/IR.cpp new file mode 100644 index 0000000000..c9fb71fc40 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/IR/IR.cpp @@ -0,0 +1,5 @@ +// +// Created by admin on 2022/6/13. +// +#include "IR.h + diff --git a/projects/PiLeiFX/ZenoFX/IR/IR.h b/projects/PiLeiFX/ZenoFX/IR/IR.h new file mode 100644 index 0000000000..22719ba096 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/IR/IR.h @@ -0,0 +1,37 @@ +// +// Created by admin on 2022/5/7. +// +#pragma once +#include +#include +#include +#include +/* + * zfx中statement就相当于一条一条的Instruction + * */ + +namespace zfx { + class Stmt ; + + class IRNode { + public: + + virtual IRNode* get_parent() const = 0; + + virtual IRNode* get_ir_root(); + + virtual ~IRNode() = default; + + //获取一个编译选项,表示怎么处理IR + // + std::unique_ptr clone();//克隆IRNode节点 + }; + class Statement { + protected: + std::vector<> + }; + + class IRVisitor { + + }; +} diff --git a/projects/PiLeiFX/ZenoFX/IR/IRBuilder.h b/projects/PiLeiFX/ZenoFX/IR/IRBuilder.h new file mode 100644 index 0000000000..ab66a4d0e5 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/IR/IRBuilder.h @@ -0,0 +1,31 @@ +// +// Created by admin on 2022/6/7. +// + +#pragma once + +#include "./BasicBlock.h" +#include "./Instruction.h" + +namespace zfx { + class IRBuilder { + public: + IRBuilder() = default; + IRBuilder(BasicBlock *bb) : bb(bb) {} + + void reset() ; + //把所有的指令清空 + + inline BasicBlock *getInsertBlock() { + return bb; + } + + void setInsertPoint(BasicBlock *bb) const { + this->bb = bb; + } + + //接下来是创建指令 + private: + BasicBlock *bb; + }; +} diff --git a/projects/PiLeiFX/ZenoFX/IR/Instruction.h b/projects/PiLeiFX/ZenoFX/IR/Instruction.h new file mode 100644 index 0000000000..0b84579f82 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/IR/Instruction.h @@ -0,0 +1,67 @@ +// +// Created by admin on 2022/6/7. +// + +#pragma once +#include "./User.h" +#include "./BasicBlock.h" +#include "./Module.h" +#include +#include + +namespace zfx { + class BasicBlock; + class Module; + class Instruction : public User { + public: + Instruction(const Instruction &) = delete; + Instruction& operator= (const Instruction &) = delete; + + const BasicBlock* getParent() const { + + } + + BasicBlock* getParent() { + + } + + const Module* getModule() const { + + } + + Module* getModule() { + + } + + + /* + * 留几个bool函数来判断指令到底是属于啥类型的 + * */ + + inline bool isUnaryOp() const { + + } + + inline bool isBinaryOp() const { + + } + + inline bool isTenaryOp() const { + + } + + void insertBefore(Instruction *InsertPos); + + void insertAfter(Instruction *InsertPos); + + void moveBefore(Instruction *MovBefore); + + + private: + BasicBlock* Parent; + + }; + + //接下来定义几个指令继承自Instruction + +} diff --git a/projects/PiLeiFX/ZenoFX/IR/Module.h b/projects/PiLeiFX/ZenoFX/IR/Module.h new file mode 100644 index 0000000000..7aa4290e63 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/IR/Module.h @@ -0,0 +1,20 @@ +// +// Created by admin on 2022/5/19. +// + +#pragma once + +namespace zfx { + class Module { + public: + explicit Module(const std::string name) : name(name) { + + } + // + virtual std::string print(); + private: + std::string name;//Module name + //need to include global variables, constants, function + std::list functions; + }; +} \ No newline at end of file diff --git a/projects/PiLeiFX/ZenoFX/IR/Type.h b/projects/PiLeiFX/ZenoFX/IR/Type.h new file mode 100644 index 0000000000..826bd6240c --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/IR/Type.h @@ -0,0 +1,81 @@ +// +// Created by admin on 2022/5/19. +// +#pragma once + +#include +#include +/* + * zfx only three types $ is the Parameter @ is the symbol, The third is the built-in function type + * compare by dimension + * */ +namespace zfx { + enum class TypeKind { + Parameter, + Symbol, + Function + }; + class ParaType; + class SymbolType; + class FunctionType; + class Type { + public: + Type(TypeKind kind, int dim) : kind(kind), dim(dim) {} + + virtual std::string ToString(); + + virtual bool LE(const Type &type) const; + + virtual bool isFunction(); + + virtual bool isParaType(); + + virtual bool isFunctionType(); + + virtual ~Type() = default; + public: + int dim; + TypeKind kind; + }; + bool operator== (const Type &lhs, const Type &rhs) const{ + if (lhs.kind != rhs.kind) { + return false; + } else { + return lhs.dim == rhs.dim; + } + return false; + } + + class ParaType : public Type{ + public: + ParaType(TypeKind kind, int dim) : Type(kind, dim) { + + } + + bool isFunctionType() override final { + return false; + } + + ~ParaType() = default; + }; + + class SymbolType : public Type { + public: + + bool LE(const Type &rhs) override { + return this->dim < rhs.dim; + } + + ~SymbolType() = default; + }; + + class FunctionType : public Type { + public: + + std::string ToString() override { + + } + + ~FunctionType() = default; + }; +} diff --git a/projects/PiLeiFX/ZenoFX/IR/TypeFinder.h b/projects/PiLeiFX/ZenoFX/IR/TypeFinder.h new file mode 100644 index 0000000000..d8302a3016 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/IR/TypeFinder.h @@ -0,0 +1,75 @@ +// +// Created by admin on 2022/5/14. +// +#pragma once + +#include "../Ast.h" +#include "Module.h" +#include +#include +/*TypeFinder - Walk various Statements, identifying various information including + * + * */ + +namespace zfx { +#define ERROR_IF(x) do { \ + if (x) { \ + error("%s", #x); \ + } \ + } while(0) + + struct TypeFinder { + using visit_emit_type = std::tuple<>; + + std::unordered_map VisitStatement ; + /* + * This is helper map to avoid repeated visit statement + * */ + void visit(Statement* stmt) { + if (VisitStatement.find(stmt) != VisitStatement.end()) { + std::cout << "this is " << std::endl; + } + VisitStatement.insert(stmt, true); + } + + // + void visit(ParamSymbolStmt* stmt) { + stmt->dim = stmt->;//设置维数 + visit((Statement*)stmt); + } + + void visit(SymbolStmt* stmt) { + stmt->dim = stmt->; + visit((Statement*)stmt); + } + + void visit(LiteralStmt* stmt) { + stmt->dim = 1; + visit((Statement*)stmt); + } + + void visit(FunctionCallStmt* stmt) { + stmt->dim = 0;//初始化维度为0 + auto const& name = stmt->name; + + //如果是vec那么就是 + if (name.substr(0, 3) == "vec" && name.size() == 4 && isdigit(name[3])) { + int dim = name[3] - '0';//字符串转换为数字 + stmt->dim = dim; + } else { + if () + //开始判断参数 + + } + + + } + + }; + + void apply_type_check(Module* m) { + TypeFinder visitor; + visitor.apply(m); + } +} + diff --git a/projects/PiLeiFX/ZenoFX/IR/User.h b/projects/PiLeiFX/ZenoFX/IR/User.h new file mode 100644 index 0000000000..dc8eae2703 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/IR/User.h @@ -0,0 +1,15 @@ +// +// Created by admin on 2022/5/19. +// + +#pragma once + +#include "Value.h" +#include + +namespace zfx { + class User : public Value { + public: + User(Type *ty, const std::) + }; +} \ No newline at end of file diff --git a/projects/PiLeiFX/ZenoFX/IR/Value.h b/projects/PiLeiFX/ZenoFX/IR/Value.h new file mode 100644 index 0000000000..0935b2db8b --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/IR/Value.h @@ -0,0 +1,48 @@ +// +// Created by admin on 2022/5/19. +// + +#pragma once + +#include "Type.h" +#include +#include +/*Value zfx中所有的数据类型都是继承于value的*/ +namespace zfx { + + class Use { + friend bool operator==() { + + } + }; + class Value { + public: + + explicit Value(Type *type, const std::string& name = ""); + + ~Value() = default; + + std::list &get_use_list() {return use_list;} + + void add_use(Value *value); + + bool set_name(std::string name) { + if (name == "") { + + } + } + + std::string get_name() const; + + void remove_use(Value *val); + + virtual std::string print() { + return ""; + } + private: + std::string name; + Type *type; + std::list use_list; + }; +} \ No newline at end of file diff --git a/projects/PiLeiFX/ZenoFX/IR/analysis.h b/projects/PiLeiFX/ZenoFX/IR/analysis.h new file mode 100644 index 0000000000..b17ed1734d --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/IR/analysis.h @@ -0,0 +1,10 @@ +// +// Created by admin on 2022/6/13. +// +//对IR做基础的分析 +#include +#include + +namespace zfx { + +} diff --git a/projects/PiLeiFX/ZenoFX/IR/constants.h b/projects/PiLeiFX/ZenoFX/IR/constants.h new file mode 100644 index 0000000000..b3144cad50 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/IR/constants.h @@ -0,0 +1,15 @@ +// +// Created by admin on 2022/6/13. +// + +#pragma once + +namespace zfx { + //zfx中的一些常量表示 + class Constant { + public: + Constant() {} + + ~Constant() = default; + }; +} \ No newline at end of file diff --git a/projects/PiLeiFX/ZenoFX/IR/statements.h b/projects/PiLeiFX/ZenoFX/IR/statements.h new file mode 100644 index 0000000000..fd1ce74f9e --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/IR/statements.h @@ -0,0 +1,32 @@ +// +// Created by admin on 2022/6/10. +// + +#pragma once + +#include "./IR.h" +#include + +namespace zfx { + //所有的操作语句都继承自Stmt + class UnaryOpStmt : public Stmt { + public: + //一元操作符的数据类型 + //操作数 + // + }; + + class BinaryOpStmt : public Stmt { + public: + //数据类型 + //左右操作数 + + }; + + class TernaryOpStmt : public Stmt { + public: + //三元操作数类型 + //三个stmt + + }; +} \ No newline at end of file diff --git a/projects/PiLeiFX/ZenoFX/Lexical.cpp b/projects/PiLeiFX/ZenoFX/Lexical.cpp new file mode 100644 index 0000000000..080f93d7d1 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/Lexical.cpp @@ -0,0 +1,61 @@ +// +// Created by admin on 2022/5/8. +// +#include "Lexical.h" +#include +#include + +namespace zfx { + std::unordered_map tokenToString { + {TokenKind::Op, "Op"}, + {TokenKind::Seprator, "Seprator"}, + {TokenKind::KeywordKind, "KeywordKind"}, + {TokenKind::Eof, "Eof"} + } + std::unordered_map OpToString { + {Op::Plus, "Plus"} , + {Op::Minus, "Minus"}, + {Op::Multiply,"Multiply"}, + {Op::Divide, "Divide"}, + {Op::Modules, "Modules"}, + {Op::L, "L"}, + {Op::G, "G"}, // > + {Op::LE, "LE"}, // <= + {Op::GE, "GE"}, // >= + {Op::MultiplyAssign, "MultiplyAssign"}, // *= + {Op::DivideAssign, "DivideAssign"}, // /= + {Op::ModulesAssign, "ModulesAssign"}, // %= + {Op::PlusAssign,"PlusAssign"}, //+= + {Op::MinusAssign, "MinusAssign"}, //-= + {Op::BitNot, "BitNot"}, //~ + {Op::BitAnd, "BitAnd"}, //&{ BitXor, //^ + {Op::BitOr, "BitOr"}, // | + {Op::At, "At"}, //@ + {Op::Comma, "Comma"}, //, + {Op::Dot, "Dot"}, //. + {Op::Not, "Not"}, // ! + {Op::And, "And"}, // && + {Op::Or, "Or"}, // || + {Op::QuesstionMark, "?"} // ? + } + std::unordered_map Scanner::KeywordMap = { + {"Pos",KeywordKind::Pos}, + {"data", KeywordKind::data}, + {"frame", KeywordKind::frame} + }; + std::string toString(TokenKind kind) { + auto it = tokenToString.find(kind); + if (it != tokenToString.end()) { + return it->second; + } + return "UnKnown"; + } + + std::string toString(Op op) { + auto it = OpToString.find(op); + if (it != OpToString.end()) { + return it->second; + } + return "UnKnown"; + } +} \ No newline at end of file diff --git a/projects/PiLeiFX/ZenoFX/Lexical.h b/projects/PiLeiFX/ZenoFX/Lexical.h new file mode 100644 index 0000000000..161b945734 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/Lexical.h @@ -0,0 +1,236 @@ +// +// Created by admin on 2022/5/7. +// +#include "Error.h" +#include +#include +#include +#pragma once + +namespace zfx { + +enum class TokenKind { + Op, + Seprator, + KeywordKind, + Decl, + Eof +}; +enum class Op { + Plus, //+ + Minus, //- + Multiply, // * + Divide, // / + Modules, // % + Assign, // = + L, // < + G, // > + LE, // <= + GE, // >= + MultiplyAssign, // *= + DivideAssign, // /= + ModulesAssign, // %= + PlusAssign, //+= + MinusAssign, //-= + BitNot, //~ + BitAnd, //& + BitXor, //^ + BitOr, // | + At, //@ + Comma, //, + Dot, //. + Not, // ! + And, // && + Or, // || + QuesstionMark // ? +}; + +enum class Seprator { + OpenBracket = 0, //[ + CloseBracket, //] + OpenParen, //( + CloseParen, //) + OpenBrace, //{ + CloseBrace, //} + Colon, //: + SemiColon, //; +}; + +enum class KeywordKind { + //for instance if while for ... to be added later as appropriate + Pos, + data, + frame, + rad, + // +}; + +enum class Decl { + Para, + Symbol +}; + +std::string toString(TokenKind kind); +std::string toString(Op op); + +struct Token { + TokenKind kind; + std::string text; + Position pos; + Token(TokenKind kind, const std::string &text, const Position &pos) : kind(kind), text(text), pos(pos) { + } + Token(TokenKind kind, char c, const Position &pos) : kind(kind), text(std::string(1, c)), pos(pos) { + } + std::string toString() { + return std::string("Token") + ":" + this->pos.toString() + this->text; + } +}; + +class CharStream { + public: + std::string data;//rep source code + uint32_t pos = 0; + uint32_t line = 1; + uint32_t col = 0; + CharStream(const std::string &data) : data(data) { + } + + char peak() { + return this->data[this->pos]; + } + + char next() { + char ch = this->data[this->pos++]; + if (ch == '\n') { + this->line++; + this->col = 0; + } else { + this->col++; + } + return ch; + } + + bool eof() { + return this->peak() == '\0'; + } + + Position getPosition() { + //return the line and column numbers of the current charactor + return Position(this->pos+1, this->pos + 1,this->line, this->col); + } +}; + + class Scanner { + private: + std::list tokens; + CharStream stream; + Position lastPos{0, 0, 0, 0}; + static std::unordered_map KeywordMap; + + public: + Scanner(CharStream &stream) : stream(stream) { + + } + Token next() { + if (this->tokens.empty()) { + auto t = this->getAToken(); + //set pos + this->lastPos = t.pos; + return t; + } else { + auto t = this->tokens.front(); + this->lastPos = t.pos; + this->tokens.pop_front(); + return t; + } + } + + Token peek() { + if (this->tokens.empty()) { + auto t = this->getAToken(); + this->tokens->push_back(t); + return t; + } else { + auto t = this->tokens.front(); + return t; + } + } + + Token peek2() { + while (this->tokens.size() < 2) { + auto t = this->getAToken(); + this->tokens.push_back(t); + } + + if (this->tokens.size() < 2) { + return Token{};//EofToken + } + + auto it = this->tokens.begin(); + std::advance(it, 1); + return *it1; + } + + private: + //getAToken主要还是由Token peek Token next这几个函数驱动 + Token getAToken() { + this->skipWhiteSpace(); + auto Pos = this->stream.getPosition(); + if (this->stream.eof()) { + return Token(TokenKind::Eof, "Eof", pos); + } else { + auto ch = this->stream.peak(); + if (this->) { + + } else if (ch == '"') { + return this->parseStringLiteral(); + } else if (ch == '$') { + this->stream.next(); + return Token(TokenKind::Decl, '$', pos); + } else if (ch == '@') { + this->stream.next(); + return Token(TokenKind::Decl, '@', pos); + } else if (this->Digit(ch)) { + + } + } else { + std::cout << "unexpected character : " + std::string(1,ch) << std::endl; + this->stream.next(); + return this->getAToken(); + } + } + + void skipSingleComment() { + this->stream.next(); + while (this->stream.peek() != '\n' && !this->stream.eof()) { + this->stream.next(); + } + } + + void skipWhiteSpace() { + while (this->isWhiteSpace(this->stream.peak())) { + this->stream.next(); + } + }; + + bool isWhiteSpace(char ch) { + return (ch == ' ' || ch == '\n', || ch == '\t'); + } + + bool isLetter(char ch) const { + return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' || ch <= 'z'); + } + + bool isLetterDigitOurUnderScore(char ch) { + return (ch >= 'A' && ch <= 'Z' || + ch >= 'a' && ch <= 'z' || + ch >= '0' && ch <= '9' || + ch == '-'); + } + + bool isDigit(char ch) { + return (ch >= '0' && ch <= '9'); + } + }; +} + diff --git a/projects/PiLeiFX/ZenoFX/LowerAST.h b/projects/PiLeiFX/ZenoFX/LowerAST.h new file mode 100644 index 0000000000..5e25e1ed19 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/LowerAST.h @@ -0,0 +1,19 @@ + +// +// Created by admin on 2022/5/18. +// +#pragma once +#include "Ast.h" +#include "IR/IR.h" +#include "Stmt.h" +#include +#include +/* + * convent ast to statement + * */ +namespace zfx { + std::tuple<> lower_ast(std::vector asts, + std::map const& symdims, + std::map const& pardims); +} + diff --git a/projects/PiLeiFX/ZenoFX/MergeIdentical.cpp b/projects/PiLeiFX/ZenoFX/MergeIdentical.cpp new file mode 100644 index 0000000000..a0b9e8f45d --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/MergeIdentical.cpp @@ -0,0 +1,23 @@ +// +// Created by admin on 2022/5/14. +// +#include "Ast.h" +#include +#include + +namespace zfx { + struct MergeIdentical { + using visit_emit_types = std::tuple<>; + + void visit() { + + } + + + }; + + std::unique_ptr<> apply_merge_identical() { + MergeIdentical visitor; + + } +} \ No newline at end of file diff --git a/projects/PiLeiFX/ZenoFX/Parser.h b/projects/PiLeiFX/ZenoFX/Parser.h new file mode 100644 index 0000000000..f91cd76a34 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/Parser.h @@ -0,0 +1,79 @@ +// +// Created by admin on 2022/5/7. +// +/* + *Prog : statementList? EOF; + *statementList : (variableDecl | functionDecl | expressionStatement); + * variableDecl : '$'|'@' Identifier + * statement : block | expressionStatement | ifStatement | forStatement + * emptyStatement | functionDecl | variableDecl + * + * ifStatement : 'if' '(' expression ') statement ('else' statement)?; + * forStatement : + * variableStatement: + * + * expression:assignment; + *Identifier : [a-zA-z][a-zA-Z0-9]*; + * IntegerLiteral : '0' | [1-9][0-9]* + * */ +#pragma once +#include "Lexical.h" +#include "Ast.h" +#include "Location.h" +#include +#include +#include + +namespace zfx { + + class Parser { + public: + Scanner& scanner; + Parser(Scanner& scanner) : scanner(scanner) { + + } + + //begin Parser and Generate Ast + std::vector Error; + std::vector Warnings; + + void addError(const std::string msg, Position pos) { + + } + + void addWarnings(const std::string msg, Position pos) { + + } + + std::shared_ptr parseVariableDecl() { + auto t = this->scanner.next(); + //解析$或者@ + if (t.kind = TokenKind::Decl) { + + } + } + + std::shared_ptr parseAssignment() { + + } + + std::shared_ptr parseBinary(int32_t prec) { + + } + + std::shared_ptr parseUnary() { + + auto t = this->scanner.peak(); + if (t.kind == TokenKind::Op) { + //前缀的一元表达式 + //跳过运算符 + this->scanner.next(); + auto exp = this->parseUnary(); + //return std::make_shared + } + } + }; + + +} + diff --git a/projects/PiLeiFX/ZenoFX/Pass.h b/projects/PiLeiFX/ZenoFX/Pass.h new file mode 100644 index 0000000000..693ef1d004 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/Pass.h @@ -0,0 +1,43 @@ +// +// Created by admin on 2022/5/25. +// + +#pragma once + +#include "IR/Module.h" +#include +namespace zfx { + using PassID = std::string; + class Pass { + public: + PassID + Pass(Module *m) {} + virtual ~Pass() ; + virtual void run() = 0; + private: + //this is zfx top-level data structure + Module *m; + }; + + class PassManger { + public: + PassManger(Module *m) : m(m) {} + template + void add_pass(bool print_ir = false) { + passes.push_back(std::pair(new Pass(m), print_ir)); + } + + void run() { + for (auto Pass : passes) { + Pass.first->run(); + if (Pass.second) { + //print ir; + } + } + } + + private: + std::vector> passes; + Module *m; + }; +} diff --git a/projects/PiLeiFX/ZenoFX/Pass/Builder_CFG.cpp b/projects/PiLeiFX/ZenoFX/Pass/Builder_CFG.cpp new file mode 100644 index 0000000000..44a16d2c24 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/Pass/Builder_CFG.cpp @@ -0,0 +1,10 @@ +// +// Created by admin on 2022/5/26. +// + +namespace zfx { + + class CFGBuilder : public IRVisitor { + + }; +} diff --git a/projects/PiLeiFX/ZenoFX/Pass/CFG.cpp b/projects/PiLeiFX/ZenoFX/Pass/CFG.cpp new file mode 100644 index 0000000000..63e45acb54 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/Pass/CFG.cpp @@ -0,0 +1,8 @@ +// +// Created by admin on 2022/5/26. +// +#include "CFG.h" + +namespace zfx { + +} \ No newline at end of file diff --git a/projects/PiLeiFX/ZenoFX/Pass/CFG.h b/projects/PiLeiFX/ZenoFX/Pass/CFG.h new file mode 100644 index 0000000000..53f298f0a4 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/Pass/CFG.h @@ -0,0 +1,57 @@ +// +// Created by admin on 2022/5/26. +// +#pragma once + +#include "../Pass.h" +#include +#include +#include + +namespace zfx { + class CFG : public Pass { + //build CFG + + public: + explicit CFG(Module *m) : Pass(m) {} + + void run() final; + + BasicBlock * getEntryBB(){ + return entry; + } + + //get those unreachable block + std::set getUnreachableBB { + return unreachable; + }; + + //Get the predecessors of a basic block (all blocks that can reach the basic block in one step) + std::set getPrevBB(BasicBlock *b) { + + } + + std::set getSuccBB(BasicBlock *b) { + + } + + std::set getTerminators() { + // + } + private: + + void cleanAll() { + //clean CFG; + entry = nullptr; + successor_map.clear(); + precessor_map.clear(); + term_set.clear(); + } + + BasicBlock *entry{nullptr}; + std::map> successor_map; + std::map> precessor_map; + std::set unreachable;//some unreachable BasicBlock used as dead code elimination + std::set term_set; + }; +} diff --git a/projects/PiLeiFX/ZenoFX/Pass/active_var.h b/projects/PiLeiFX/ZenoFX/Pass/active_var.h new file mode 100644 index 0000000000..904d8a6a3d --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/Pass/active_var.h @@ -0,0 +1,23 @@ +// +// Created by admin on 2022/5/31. +// +#include "../Pass.h" +#include "../IR/BasicBlock.h" +#include +#include +//用来死代码删除 +namespace zfx { + class ActiveVars : public Pass { + public: + explicit ActiveVars(Module *m) : Pass(M) {} + void run() override; + std::unordered_set getLiveOut(BasicBlock *bb); + std::unordered_set getLiveIn(BasicBlock *bb); + bool isLiveOut() { + + } + + private: + + }; +} diff --git a/projects/PiLeiFX/ZenoFX/Pass/const_flold.h b/projects/PiLeiFX/ZenoFX/Pass/const_flold.h new file mode 100644 index 0000000000..4f70dca3b9 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/Pass/const_flold.h @@ -0,0 +1,16 @@ +// +// Created by admin on 2022/6/11. +// + +#pragma once + +#include "../Pass.h" +//让所有的优化都基于ir中的那个pass 类 +namespace zfx { + class ConstantFoldPass : public Pass { + public: + //用一个id去标记一下 + //用Program代表优化后的对象 + + }; +} \ No newline at end of file diff --git a/projects/PiLeiFX/ZenoFX/Pass/die.cpp b/projects/PiLeiFX/ZenoFX/Pass/die.cpp new file mode 100644 index 0000000000..5a78d59313 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/Pass/die.cpp @@ -0,0 +1,5 @@ +// +// Created by admin on 2022/6/11. +// + +//死代码消除 diff --git a/projects/PiLeiFX/ZenoFX/Statement.h b/projects/PiLeiFX/ZenoFX/Statement.h new file mode 100644 index 0000000000..30810fcfa7 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/Statement.h @@ -0,0 +1,77 @@ +// +// Created by admin on 2022/5/14. +// +#pragma once +#include "Ast.h" +#include +#include +/*Statement you can think of it as one High IR based ast, + * and for the time + * */ + +namespace zfx { + + strcut Statement; + using StmtFields = std::vector>; + using RegFields = std::vector; + + struct Statement { + int id;// + int dim = 0;//dimensionality; + explicit Statement(int id , int dim) : id(id), dim(dim) { + + } + + std::string print() { + return ; + } + + virtual std::string to_string() = 0; + + virtual std::unique_ptr clone(int newid) const = 0; + + virtual StmtFields fields() = 0; + + virtual ~Statement() = default; + + virtual std::string serialize_identity() const { + return to_string(); + } + + virtual bool is_control_stmt() const { + return false; + } + + + }; + + template + struct Stmt : Statement { + using Statement::Statement; + + virtual std::unique_ptr clone(int newid) override { + auto ret = std::make_unique(static_cast*this); + ret->id = newid; + return ret; + } + }; + + template + struct AsmStmt: Stmt { + using Stmt::Stmt; + + virtual StmtFields fields() override { + + } + }; + + struct EmptyStmt : Stmt { + explicit EmptyStmt(int id_) : Stmt(id_) {} + + virtual StmtFields fields() override { + return {}; + } + }; +} + + diff --git a/projects/PiLeiFX/ZenoFX/Stmt.h b/projects/PiLeiFX/ZenoFX/Stmt.h new file mode 100644 index 0000000000..2721859be4 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/Stmt.h @@ -0,0 +1,34 @@ +// +// Created by admin on 2022/5/17. +// + +#include "Statement.h" + +namespace zfx { + struct UnaryOpStmt : Stmt { + std::string op; + Statement *src; + UnaryOpStmt(int id, const std::string op, Statement* src) : Stmt(id), op(op), src(src) { + + } + + virtual StmtFields fields() override { + return { + src, + };// + } + + }; + + struct VectorSwizzleStmt : Stmt { +//转换坐标 + + }; + + struct VectorComposeStmt : Stmt { + int dimension; + std::vector args; + + VectorComposeStmt(int id, int dimension, std::vector*) + }; +} diff --git a/projects/PiLeiFX/ZenoFX/Symbol.cpp b/projects/PiLeiFX/ZenoFX/Symbol.cpp new file mode 100644 index 0000000000..58013d11bb --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/Symbol.cpp @@ -0,0 +1,14 @@ +// +// Created by admin on 2022/5/12. +// + +#include "Symbol.h" +#include + +namespace zfx { + /* + std::map> built_ins { + + }; + */ +} diff --git a/projects/PiLeiFX/ZenoFX/Symbol.h b/projects/PiLeiFX/ZenoFX/Symbol.h new file mode 100644 index 0000000000..49902f1e5b --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/Symbol.h @@ -0,0 +1,74 @@ + +// +// Created by admin on 2022/5/11. +// +/* + * this is Symbol table + * save variable name , variable kind and variable dimensional + * if there are other needs in the future , we will add + * */ +#pragma once + +#include +#include +#include +#include +#include + +namespace zfx { + + enum class SymKind{Variable, Function}; + enum class SymDim{ + zero = 0, + OneDimensional = 1, + TwoDimensional = 2, + ThreeDimensional = 3, + FourDimensional = 4 + }; + class VarSymbol; + class FunctionSymbol; + class Symbol { + public: + std::string name; + SymKind kind; + SymDim dim; + Symbol(const std::string& name, SymKind kind, SymDim dim) {} + + virtual std::any accept(SymbolVisitor& visitor, std::string additional) = 0; + }; + + class SymbolVisitor { + public: + virtual std::any visitVarSymbol(VarSymbol& sym, std::string additional); + virtual std::any visitFunctionSymbol(FunctionSymbol& sym, std::string additional); + + }; + + class VarSymbol : public Symbol { + public: + VarSymbol(const std::string& name, SymKind kind, SymDim dim) : Symbol(name, kind, dim){ + + } + + std::any accept(SymbolVisitor& visitor, std::string additional) { + return visitor.visitVarSymbol(*this, additional); + } + }; + + class FunctionSymbol : public Symbol { + public: + FunctionSymbol(const std::string name, SymKind kind, SymDim dim) : Symbol(name, kind, kind) { + + } + + std::any accept(SymbolVisitor& visitor, std::string additional) { + return visitor.visitFunctionSymbol(*this, additional); + } + + }; + class SymbolDumper : public SymbolVisitor{ + + }; + //extern std::map> built_ins; + +} diff --git a/projects/PiLeiFX/ZenoFX/SymbolCheck.cpp b/projects/PiLeiFX/ZenoFX/SymbolCheck.cpp new file mode 100644 index 0000000000..9286ef41c1 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/SymbolCheck.cpp @@ -0,0 +1,9 @@ +// +// Created by admin on 2022/5/14. +// + +#include "Ast.h" +#include " +namespace zfx { + +} diff --git a/projects/PiLeiFX/ZenoFX/ZFXContext.h b/projects/PiLeiFX/ZenoFX/ZFXContext.h new file mode 100644 index 0000000000..0236b147a3 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/ZFXContext.h @@ -0,0 +1,11 @@ +// +// Created by admin on 2022/5/16. +// + +#pragma once + +#include + +namespace zfx { + +} diff --git a/projects/PiLeiFX/ZenoFX/cuda/CAssembler.cpp b/projects/PiLeiFX/ZenoFX/cuda/CAssembler.cpp new file mode 100644 index 0000000000..9e8c1b9b96 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/cuda/CAssembler.cpp @@ -0,0 +1,14 @@ +// +// Created by admin on 2022/5/9. +// + +#include + +namespace zfx::cuda { + + struct CUDABuilder { + + }; +} + +std::string diff --git a/projects/PiLeiFX/ZenoFX/cuda/context.h b/projects/PiLeiFX/ZenoFX/cuda/context.h new file mode 100644 index 0000000000..9aa37699d9 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/cuda/context.h @@ -0,0 +1,12 @@ +// +// Created by admin on 2022/5/9. +// + +#pragma once + +namespace zfx::cuda { + class CUcontext { + + + }; +} diff --git a/projects/PiLeiFX/ZenoFX/general_struct.h b/projects/PiLeiFX/ZenoFX/general_struct.h new file mode 100644 index 0000000000..825741582b --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/general_struct.h @@ -0,0 +1,20 @@ +// +// Created by admin on 2022/5/19. +// +#pragma once + +#include +#include +#include + +namespace zfx { + class Module { + public: + std::string name; + //module name actually file name + Module(std::string name) : name(name) {} + Module() : name("Module") {} + virtual ~Module() {} + virtual void EmitCode() = 0; + }; +} diff --git a/projects/PiLeiFX/ZenoFX/include/cuda.h b/projects/PiLeiFX/ZenoFX/include/cuda.h new file mode 100644 index 0000000000..3732120d5c --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/include/cuda.h @@ -0,0 +1,8 @@ +// +// Created by admin on 2022/5/9. +// +#pragma once + +namespace zfx::cuda { + +} diff --git a/projects/PiLeiFX/ZenoFX/include/x64.h b/projects/PiLeiFX/ZenoFX/include/x64.h new file mode 100644 index 0000000000..ef2fb752a0 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/include/x64.h @@ -0,0 +1,306 @@ +// +// Created by admin on 2022/5/7. +// +//试验性的将zfx转成x64汇编代码 +#pragma once + +#include +#include +namespace zfx::x64 { + /* + struct Executable { + + }; + + struct Assembler { + std::map> cache; + + }; + */ + + enum AsmOpCode { + jmp=0, + je, + jne, + jle, + jl, + jge, + jg, + jbe, + jb, + jae, + ja, + + sete=20, + setne, + setl, + setle, + setg, + setge, + + //8字节指令 + movq=40, + addq, + subq, + mulq, + imulq, + divq, + idivq, + negq, + incq, + decq, + xorq, + orq, + andq, + notq, + leaq, + callq, + retq, + pushq, + popq, + cmpq, + + //4字节指令 + movl=80, + addl, + subl, + mull, + imull, + divl, + idivl, + negl, + incl, + decl, + xorl, + orl, + andl, + notl, + leal, + calll, + retl, + pushl, + popl, + cmpl, + + //2字节指令 + movw=120, + addw, + subw, + mulw, + imulw, + divw, + idivw, + negw, + incw, + decw, + xorw, + orw, + andw, + notw, + leaw, + callw, + retw, + pushw, + popw, + cmpw, + + //单字节指令 + movb=160, + addb, + subb, + mulb, //无符号乘 + imulb, //有符号乘 + divb, //无符号除 + idivb, //有符号除 + negb, + incb, + decb, + xorb, + orb, + andb, + notb, + leab, + callb, + retb, + pushb, + popb, + cmpb, + + //SSE指令 + movsd = 200, + addsd, + subsd, + mulsd, + divsd, + sqrtsd, + maxsd, + minsd, + cmpsd, + comisd, + ucomisd, + + cvttsd2si = 240, //double 到long或int都可以,会导致截断, 第一个操作数可以是内存 + cvtsi2sdq, //从long到double + + + //伪指令 + declVar = 300, //变量声明 + reload, //重新装载被溢出到内存的变量到寄存器 + tailRecursive, //尾递归的函数调用 + tailCall, //尾调用 + tailRecursiveJmp, //尾递归产生的jmp指令,操作数是一个基本块,是序曲下的第一个基本块。 + tailCallJmp, //尾调用产生的jmp指令,操作数是一个字符串(标签) + }; + /* + * 操作数的类型 + * */ + enum OprandKind { + varIndex, //变量下标 + returnSlot,//用于存放返回值的位置 + bb,//调准指令指向的基本快 + function,//函数调用 + stringConst,//字符串常量 + + }; + class OpCodeHelper { + public: + static bool isReturn(AsmOpCode op) { + return op == AsmOpcode::retb || op == AsmOpcode::retw || op == AsmOpcode.retl || op == AsmOpcode::retq; + } + + static bool isJump(AsmOpCode op) { + return op < AsmOpcode; + } + + static bool isMov() { + + } + + }; + + class Oprand{ + public: + OprandKind kind; + std::string name; + + //判断操作数是否相同 + bool isSame() + virtual std::string toString() { + + } + }; + + class Inst { + public: + AsmOpCode op; + static uint32_t index;//下标 + uint32_t numOpRands; + std::string comment; + Inst(AsmOpCode op, uint32_t numOpRands) : op(op), numOpRands(numOpRands) { + index++; + } + + virtual bool is_Inst_0() { + return false; + } + + virtual bool is_Inst_1() { + return false; + } + + virtual bool is_Inst_2() { + return false; + } + virtual std::string toString() = 0; + }; + + + //没有操作数的指令 + class Inst_0 : public Inst{ + public: + // + }; + + class Inst_1 : public Inst { + public: + std::shared_ptr oprand; + bool is_Inst1() override { + return true; + } + + std::string toString() override { + auto str = + } + }; + + class Inst_2 : public Inst { + public: + std::shared_ptr oprand1; + std::shared_ptr oprand2; + + bool isInst_2() override { + return true; + } + + std::string toString() override { + + } + + }; + + class BasicBlock { + public: + std::vector> insts;//基本快内的指令 + int32_t funcIndex{-1};//函数编号 + int32_t bbIndex {-1};//基本块编号 + //是否有其他快跳转到该块 + bool isDestination{false}; + + std::string getName() { + + } + + std::string toString() { + std::string str; + + return str; + } + }; + //变量活跃性分析结果 + struct LivenessResult { + std::map, std::set> liveVars; + std::map, std::set> initalVars; + }; + class AsmModule { + public: + + /* + * 输出代表一个模块的asm文件字符串 + * */ + std::string toString() { + std::string str; + + return std::move(str); + } + }; + //当前汇编依靠直接便令Ast生成,并没有用到自定义ir + class AsmGenerator : public AstVisitor { + public: + std::shared_ptr asmModule; + + //存放一些临时变量 + //std::shared_ptr s; + std::shared_ptr returnSlot; + AsmGenerator() { + this->asmModule = std::make_shared(); + this->returnSlot = std::make_shared(); + } + + //接下来就是用访问者模式生成asm + std::any visitVariable(Variable& variable, std::string prefix) override { + + } + + + }; +} diff --git a/projects/PiLeiFX/ZenoFX/include/zfx.h b/projects/PiLeiFX/ZenoFX/include/zfx.h new file mode 100644 index 0000000000..c93090e765 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/include/zfx.h @@ -0,0 +1,76 @@ +// +// Created by admin on 2022/5/6. +// + +#pragma once + +#include +#include +#include +#include +#include + +namespace zfx { +//可以单独设置一个表示arch的同文件 + struct Options { + //一些基本设置参数加优化选项 + + // Options two + int simd_width; + int arch_max_regs{16}; + bool const_fold {false}; + bool kill_unreachable_code {false}; + constexpr struct {} for_x64{}; + + constexpr struct {} cuda{}; + Options(decltype(for_x64)) {} + + Options(int a) {} + }; + class CompileError { + + private: + std::string message; + + }; + struct Program { + std::vector> symbols; + std::vector> params; + std::string assembly; + + auto const& get_assembly() { + return assembly; + } + + auto const& get_symbols() { + return symbols; + } + + auto const& get_params() { + + } + + void + + }; + + struct Compiler { + std::map> cache; + + Program *compile(const std::string &code, const Options &option) { + std::ostringstream ss; + ss << code << ""; + + auto key = ss.str(); + auto it = cache.find(key); + if (it != cache.end()) { + return it->second; + } + + } + + }; + + +} + diff --git a/projects/PiLeiFX/ZenoFX/jit_module.h b/projects/PiLeiFX/ZenoFX/jit_module.h new file mode 100644 index 0000000000..4c914f5c0c --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/jit_module.h @@ -0,0 +1,11 @@ +// +// Created by admin on 2022/5/25. +// +#pragma once + +namespace zfx { + class JITModule { + public: + + }; +} diff --git a/projects/PiLeiFX/ZenoFX/parser.cpp b/projects/PiLeiFX/ZenoFX/parser.cpp new file mode 100644 index 0000000000..42bba14ccd --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/parser.cpp @@ -0,0 +1,6 @@ +// +// Created by admin on 2022/5/7. +// + +#include "parser.h" + diff --git a/projects/PiLeiFX/ZenoFX/visitor.h b/projects/PiLeiFX/ZenoFX/visitor.h new file mode 100644 index 0000000000..e5cebb04ed --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/visitor.h @@ -0,0 +1,31 @@ +// +// Created by admin on 2022/5/8. +// + +#pragma once + +#include "IR/Module.h" +#include +#include +/* + * This is a semantic analysis module + * */ +namespace zfx { + void apply_control_check(Module *m); + void apply_symbol_check(Module *m); + void apply_type_check(Module *m); + std::map apply_detect_new_symbols(Module *m, + std::mapconst &temps, + std::vector& symbols>); + std::unique_ptr apply_expand_function(Module *m); + std::unique_ptr apply_lower_math(Module *m); + std::unique_ptr apply_demote_math_funcs(Module *m); + + + /* + * + * + * */ + + std::string apply_emit_assembly(Module* m); +} \ No newline at end of file diff --git a/projects/PiLeiFX/ZenoFX/vm.h b/projects/PiLeiFX/ZenoFX/vm.h new file mode 100644 index 0000000000..b6abaac99c --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/vm.h @@ -0,0 +1,91 @@ +// +// Created by admin on 2022/5/13. +// + +#pragma once +//this is a trial stack machine base Ast tree +#include "Lexical.h +#include "Ast.h" +#include "Symbol.h" +#include +#include +namespace zfx { + enum class OpCode { + // + }; + + class BCModule { + //This is a bitcode module + std::shared_ptr _main;// + + std::vector consts;//常量值 + + BCModule() { + //construct function 将内置函数加入到常量池 + } + }; + + classBCModuleDumper { + + }; + + class StackFrame { + + }; + class BCGenerator : public AstVisitor { + public: + std::shared_ptr m;//编译后生成的模型 + std::shared_ptr functionSym; + + BCGenerator() { + this->m = std::make_shared(); + } + + std::any visitVariable(Variable& variable, std::string additional) override { + + } + + std::any visitFunctionCall(FunctionCall& functionCall, std::string additional) override { + + } + + std::any visitBinary(Binary& binary, std::strig additional) { + + } + + std::any visitUnary(Unary& unary, std::string additional) override { + + } + + std::any visitTenary(Tenary& tenary, std::string additional) override { + + } + + std::any visitAssign(AssignStmt& assign, std::string additional) override { + + } + + std::any visitLiteral(Literal& literal, std::string additional) override { + + } + + std::any visitIfStmt(ExprIfStmt& exprIfStmt, std::string additional) override { + + } + + }; + + class VM { + public: + //this + + int32_t execute(const BCModule& bcModule) { + //找到入口函数 + std::shared_ptr functionSym; + if (bcModule._main == nullptr) { + std::cout << "Can not find main function" << std::endl; + return -1; + } + } + }; +} diff --git a/projects/PiLeiFX/ZenoFX/x64/Assembler.h b/projects/PiLeiFX/ZenoFX/x64/Assembler.h new file mode 100644 index 0000000000..31cb7af723 --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/x64/Assembler.h @@ -0,0 +1,58 @@ +// +// Created by admin on 2022/5/7. +// + +#pragma once +#include +#include + +//cpp17 +namespace zfx ::x64{ + enum class AsmOpCode { + + }; + + enum class AsmJmpCode { + + }; + + enum class OpReg { + + }; + + enum class SimdType { + + }; + + enum class OprandKind { + + }; + struct SimdBuilder { + std::vector + }; + + class Inst { + + }; + + class Inst_0 { + // + }; + + class Inst_1 { + + }; + + class Inst_2 { + + }; + + class Oprand{ + + }; + + class MemAddress { + + }; +} + diff --git a/projects/PiLeiFX/ZenoFX/x64/BuilderAssembler.cpp b/projects/PiLeiFX/ZenoFX/x64/BuilderAssembler.cpp new file mode 100644 index 0000000000..fd32a1c60f --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/x64/BuilderAssembler.cpp @@ -0,0 +1,17 @@ +// +// Created by admin on 2022/5/10. +// +#include + +namespace zfx { + #define ERROR_IF(x) do { \ + if(x) { \ + error("%s", #x); \ + } \ + } while(0) + + struct ImplAssembler { + + }; +} + diff --git a/projects/PiLeiFX/ZenoFX/x64/Func.h b/projects/PiLeiFX/ZenoFX/x64/Func.h new file mode 100644 index 0000000000..2996b16f7b --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/x64/Func.h @@ -0,0 +1,13 @@ +// +// Created by admin on 2022/5/10. +// + +#pragma once +#include + +namespace zfx::x64 { + struct BuiltFunc { + #define DEF_FUN1(name) static void func_##name(float *a) {} + #define DEF_FUN2(name) static void func_##name(float *a , float *b) {} + }; +} \ No newline at end of file diff --git a/projects/PiLeiFX/ZenoFX/zfx.cpp b/projects/PiLeiFX/ZenoFX/zfx.cpp new file mode 100644 index 0000000000..9e1b2db17b --- /dev/null +++ b/projects/PiLeiFX/ZenoFX/zfx.cpp @@ -0,0 +1,49 @@ +// +// Created by admin on 2022/5/8. +// +#include "include/zfx.h" +#include +#include "parser.h" +namespace zfx { +/* + * zfx + * + * */ +std::tuple<> compile_to_assembly (const std::string& code, const Options& options) { +#ifdef ZFX_PRINT_IR + std::cout << "start zfx" << std::endl; + std::cout << code << std::endl; +#endif +#ifdef ZFX_PRINT_IR + std::cout << "scanner Token" << std::endl; + //here may output print tokens; +#endif +#ifdef ZFX_PRINT_IR + std::cout << "Parse Ast" << std::endl; + + //here i want to print ast tree; +#endif +#ifdef ZFX_PRINT_IR + std::cout << "Transform IR" << std::endl; + //output IR; +#endif +//There is a problem + //begin Semantic Analysis +#ifdef ZFX_PRINT_IR + std::cout << "Controlcheck" << std::endl; +#endif +#ifdef ZFX_PRINT_IR + std::cout << "SymbolCheck" << std::endl; +#endif +#ifdef ZFX_PRINT_IR + std::cout << "TypeCheck" << std::endl; +#endif + +#ifdef ZFX_PRINT_IR + std::cout << "Assemble" << std::endl; +#endif +} + + +} + diff --git a/projects/ZenoFX/CMakeLists.txt b/projects/ZenoFX/CMakeLists.txt index c7b83083f0..ac9296a245 100644 --- a/projects/ZenoFX/CMakeLists.txt +++ b/projects/ZenoFX/CMakeLists.txt @@ -3,7 +3,7 @@ add_subdirectory(ZFX) target_include_directories(zeno PRIVATE .) target_link_libraries(zeno PRIVATE $) -target_sources(zeno PRIVATE nw.cpp pw.cpp pnw.cpp ppw.cpp pew.cpp dbg_printf.h) +target_sources(zeno PRIVATE nw.cpp pw.cpp pnw.cpp ppw.cpp pew.cpp ne.cpp dbg_printf.h) if (ZENO_WITH_zenvdb) option(ZENOFX_ENABLE_OPENVDB "Enable OpenVDB wrangler in ZenoFX" ON) diff --git a/projects/ZenoFX/ZFX/IRVisitor.h b/projects/ZenoFX/ZFX/IRVisitor.h index faebf0b565..3010ed7ecd 100644 --- a/projects/ZenoFX/ZFX/IRVisitor.h +++ b/projects/ZenoFX/ZFX/IRVisitor.h @@ -16,7 +16,8 @@ struct IRVisitor { }; template -struct Visitor : IRVisitor { +struct + Visitor : IRVisitor { using IRVisitor::apply; virtual void apply(Statement *stmt) override { diff --git a/projects/ZenoFX/ZFX/KillUnreachable.cpp b/projects/ZenoFX/ZFX/KillUnreachable.cpp index 2163dc2daa..f23ddd0762 100644 --- a/projects/ZenoFX/ZFX/KillUnreachable.cpp +++ b/projects/ZenoFX/ZFX/KillUnreachable.cpp @@ -32,6 +32,7 @@ struct GatherReachable : Visitor { auto stmtid = it->second; deps[stmt->id].insert(stmtid); } + for (int r: dst) { regs[r] = stmt->id; } diff --git a/projects/ZenoFX/ZFX/Lexical.h b/projects/ZenoFX/ZFX/Lexical.h index 848d4fa91f..27e69e06ed 100644 --- a/projects/ZenoFX/ZFX/Lexical.h +++ b/projects/ZenoFX/ZFX/Lexical.h @@ -4,16 +4,32 @@ namespace zfx { -inline char opchars[] = "+-*/%=(),.;<>!&|^?:"; -inline std::set opstrs = { +//inline char opchars[] = "+-*/%=(),.;<>!&|^?:"; +// +enum class Op { + '+'; + '-' + +}; + +/*inline std::set opstrs = { "(", ")", ",", ".", ";", "+", "-", "*", "/", "%", "=", "+=", "-=", "*=", "/=", "%=", "==", "!=", "<", "<=", ">", ">=", "&", "&!", "|", "^", "!", "?", ":", }; +*/ +enum class Seprator { + '(', + + +}; + +inline bool + -inline bool is_literial_atom(std::string const &s) { +is_literial_atom(std::string const &s) { if (!s.size()) return false; if (isdigit(s[0]) || s.size() > 1 && s[0] == '-' && isdigit(s[1])) { return true; diff --git a/projects/ZenoFX/ZFX/cuda/NVRTC.cuh b/projects/ZenoFX/ZFX/cuda/NVRTC.cuh index d6bc98a2b0..456e6f93a7 100644 --- a/projects/ZenoFX/ZFX/cuda/NVRTC.cuh +++ b/projects/ZenoFX/ZFX/cuda/NVRTC.cuh @@ -127,6 +127,7 @@ static CUmodule compileJITModule #if 0 + int main() { CU(cuInit(0)); diff --git a/projects/ZenoFX/ZFX/include/zfx/zfx.h b/projects/ZenoFX/ZFX/include/zfx/zfx.h index 324468df2c..c4e9470c1c 100644 --- a/projects/ZenoFX/ZFX/include/zfx/zfx.h +++ b/projects/ZenoFX/ZFX/include/zfx/zfx.h @@ -9,12 +9,11 @@ #include namespace zfx { - struct Options { bool const_parametrize = true; bool global_localize = true; bool demote_math_funcs = true; - bool save_math_registers = true; + bool save_math_registwmers = true; int arch_maxregs = 16; bool detect_new_symbols = false; @@ -51,11 +50,11 @@ struct Options { void define_symbol(std::string const &name, int dimension) { symdims[name] = dimension; } - +//插入定义的符号 void define_param(std::string const &name, int dimension) { pardims[name] = dimension; } - +//插入参数 void dump(std::ostream &os) const { for (auto const &[name, dim]: symdims) { os << '/' << name << '/' << dim; @@ -80,10 +79,10 @@ std::tuple ( std::string const &code , Options const &options ); - +//分别是code symbol params new symbol; struct Program { std::vector> symbols; - std::vector> params; + std::vector> params;@ 和$ std::map newsyms; std::string assembly; diff --git a/projects/ZenoFX/ZFX/test.cpp b/projects/ZenoFX/ZFX/test.cpp new file mode 100644 index 0000000000..aad89f6586 --- /dev/null +++ b/projects/ZenoFX/ZFX/test.cpp @@ -0,0 +1,3 @@ +// +// Created by admin on 2022/6/15. +// diff --git a/projects/ZenoFX/ZFX/zfx.cpp b/projects/ZenoFX/ZFX/zfx.cpp index 045cfd3875..a9afe50786 100644 --- a/projects/ZenoFX/ZFX/zfx.cpp +++ b/projects/ZenoFX/ZFX/zfx.cpp @@ -78,6 +78,7 @@ std::tuple newsyms = apply_detect_new_symbols( ir.get(), temporaries, symbols); #ifdef ZFX_PRINT_IR + ir->print(); #endif } diff --git a/projects/ZenoFX/ne.cpp b/projects/ZenoFX/ne.cpp new file mode 100644 index 0000000000..875c9f6ee4 --- /dev/null +++ b/projects/ZenoFX/ne.cpp @@ -0,0 +1,144 @@ +// +// Created by admin on 2022/6/15. +// + +#include +#include + +#include +#include +#include +#include +#include "dbg_printf.h" + +namespace { + static zfx::Compiler compiler; + static zfx::x64::Assembler assembler; + + static void numeric_eval (zfx::x64::Executable *exec, + std::vector &chs) { + auto ctx = exec->make_context(); + for (int j = 0; j < chs.size(); j++) { + ctx.channel(j)[0] = chs[j]; + } + ctx.execute(); + for (int j = 0; j < chs.size(); j++) { + chs[j] = ctx.channel(j)[0]; + } + + } + + struct NumericEval : zeno::INode { + virtual void apply() { + auto code = get_input("zfxCode")->get(); +//一个模板函数,返回一个std::shared_ptr,这里对这一个智能指针调用get()返回一个裸指针 + zfx::Options opts(zfx::Options::for_x64); + opts.detect_new_symbols = true; + + //接收参数 + auto params = has_input("params") ? get_input("params") : + std::make_shared(); + + std::vector parvals;//存储参数值 + std::vector> parnames; + for (auto const &[key_, obj] : params->lut) { + //lut是DictObject中的一个map + //zany是std::shared_ptr的别名 + auto key = '$' + key_; + auto par = zeno::objectToLiterial(obj); + //par 是一个NumericValue + //ObjectToLiterial是一个模板函数由两个重载一个返回bool, 一个返回T + //获取参数的维数 + auto dim = std::visit([&](auto const &v){ + using T = std::decay_t; + //判断参数是三维数组还是,单浮点数 + if constexpr(std::is_same_v(T, zeno::vec3f)) { + parvals.push_back(v[0]); + parvals.push_back(v[1]); + parvals.push_back(v[2]); + parnames.emplace_back(key, 0); + paranames.emplace_back(key, 1); + paranames.emplace_back(key, 2); + return 3; + } else if constexpr(std::is_constructible_v) { + parvals.push_back(float(v)); + paranames(emplace_back(key, 0)); + return 1; + } else return 0; + }, par); + dbg_print("define param : %s dim %d\n, key.c_str(), dim"); + opts.define_param(key, dim); + } + + //开始编译 + auto prog = compiler.compile(code, opts); + auto exec = assembler.assemble(prog->assembly); + + //计算输出结果 + auto result = std::make_shared(); + for (auto const &[name, dim] : prog->newsyms) { + dbg_printf("output numeric value %s with dim %d\n", name.c_str(), dim); + assert(name[0] == '@'); + auto key = name.substr(1); + zeno::NumericValue value; + if (dim == 4) { + value = zeno::vec4f{}; + } else if (dim == 3) { + value = zeno::vec3f{}; + } else if (dim == 2) { + value = zeno::vec2f{}; + } else if (dim == 1) { + value = float{}; + } else { + dbg_printf("ERROR : bad output dimension for numeric : %d\n", dim); + abort(); + } + } + result->set(value); + //result->lut[key] = std::make_shared(value); + } + + for (int i = 0; i < prog->params.size(); i++) { + auto [name, dimid] = prog->params[i]; + dbg_printf("parameter %d: %s.%d\n", i , name.c_str(), dimid); + assert(name[0] == '$'); + auto it = std::find(parnames.begin(), paranames.end(), std::pair{name , dimid}); + auto value = parvals.at(it - paranames.begin()); + dbg_printf("(value %f)\n", value); + exec->parameter(prog->param_id(name, dimid)) = value; + } + + std::vector chs(prog->symbols.size());//初始化chs的大小 + for (int i = 0; i < chs.size(); i++) { + auto [name, dimid] = prog->symbols[i]; + dbg_printf("output %d : %s.%d\n", i, name.c_str(), dimid); + assert(name[0] == '@'); + } + + numeric_eval(exec, chs); + + for (int i = 0; i < chs.size(); i++) { + auto [name, dimid] = prog->symbols[i]; + float value = chs[i]; + dbg_printf("output %d : %s. %d = %f\n", i , name.c_str(), dimid, value); + auto key = name.substr(1); + std::visit([dimid = dimid, value] (auto &res) { + dimid[(float*)(void*)&res] = value; + }, result->get()) + } + set_output("result", std::move(result)); + }; + + ZENDEFNODE(NumericEval, { + /* inputs*/ + { + {"DictObject:NumericObject", "params"}, {"string", "zfxCode"} + }, + /*OutPut*/ + { + {"NumericObject", "result"} + }, + {}, + {"zenofx"}, + }); +} diff --git a/projects/ZenoFX/ppw.cpp b/projects/ZenoFX/ppw.cpp index b04b758505..0e7c9c30eb 100644 --- a/projects/ZenoFX/ppw.cpp +++ b/projects/ZenoFX/ppw.cpp @@ -7,7 +7,8 @@ #include #include #include "dbg_printf.h" - +//this is git test +//this is git test2 namespace { static zfx::Compiler compiler; diff --git a/projects/ZenoFX/pw.cpp b/projects/ZenoFX/pw.cpp index 2fd1e8c981..006194f0b9 100644 --- a/projects/ZenoFX/pw.cpp +++ b/projects/ZenoFX/pw.cpp @@ -59,7 +59,6 @@ struct ParticlesWrangle : zeno::INode { virtual void apply() override { auto prim = get_input("prim"); auto code = get_input("zfxCode")->get(); - zfx::Options opts(zfx::Options::for_x64); opts.detect_new_symbols = true; prim->foreach_attr([&] (auto const &key, auto const &attr) {