set structure for IR
This commit is contained in:
3
include/IR/IR.h
Normal file
3
include/IR/IR.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "IR_basic.h"
|
||||||
|
#include "IRBuilder.h"
|
54
include/IR/IRBuilder.h
Normal file
54
include/IR/IRBuilder.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include <memory>
|
||||||
|
#include "IR_basic.h"
|
||||||
|
#include "ast/astnode_visitor.h"
|
||||||
|
class IRBuilder : public ASTNodeVirturalVisitor {
|
||||||
|
std::shared_ptr<ModuleItem> prog;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Structural AST Nodes
|
||||||
|
void ActuralVisit(FuncDef_ASTNode *node) override;
|
||||||
|
void ActuralVisit(ClassDef_ASTNode *node) override;
|
||||||
|
void ActuralVisit(Program_ASTNode *node) override;
|
||||||
|
|
||||||
|
// Statement AST Nodes
|
||||||
|
void ActuralVisit(EmptyStatement_ASTNode *node) override;
|
||||||
|
void ActuralVisit(DefinitionStatement_ASTNode *node) override;
|
||||||
|
void ActuralVisit(ExprStatement_ASTNode *node) override;
|
||||||
|
void ActuralVisit(IfStatement_ASTNode *node) override;
|
||||||
|
void ActuralVisit(WhileStatement_ASTNode *node) override;
|
||||||
|
void ActuralVisit(ForStatement_ASTNode *node) override;
|
||||||
|
void ActuralVisit(JmpStatement_ASTNode *node) override;
|
||||||
|
void ActuralVisit(SuiteStatement_ASTNode *node) override;
|
||||||
|
|
||||||
|
// Expression AST Nodes
|
||||||
|
void ActuralVisit(NewArrayExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(NewConstructExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(NewExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(AccessExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(IndexExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(SuffixExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(PrefixExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(OppositeExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(LNotExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(BNotExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(MDMExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(PMExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(RLExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(GGLLExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(NEExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(BAndExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(BXorExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(BOrExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(LAndExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(LOrExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(TernaryExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(AssignExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(ThisExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(ParenExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(IDExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(FunctionCallExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(FormattedStringExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(ConstantExpr_ASTNode *node) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<ModuleItem> BuildIR(std::shared_ptr<Program_ASTNode> src);
|
143
include/IR/IR_basic.h
Normal file
143
include/IR/IR_basic.h
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <ios>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
#include "ast/astnode.h"
|
||||||
|
struct LLVMIRIntType {
|
||||||
|
size_t bits;
|
||||||
|
};
|
||||||
|
struct LLVMIRPTRType {};
|
||||||
|
struct LLVMIRCLASSTYPE {};
|
||||||
|
using LLVMType = std::variant<LLVMIRIntType, LLVMIRPTRType, LLVMIRCLASSTYPE>;
|
||||||
|
class LLVMIRItemBase {
|
||||||
|
public:
|
||||||
|
LLVMIRItemBase() = default;
|
||||||
|
virtual ~LLVMIRItemBase() = default;
|
||||||
|
virtual void RecursivePrint(std::ostream &os) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TypeDefItem : public LLVMIRItemBase {
|
||||||
|
public:
|
||||||
|
void RecursivePrint(std::ostream &os) const { ; }
|
||||||
|
};
|
||||||
|
class GlobalVarDefItem : public LLVMIRItemBase {
|
||||||
|
LLVMType type;
|
||||||
|
std::string name;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void RecursivePrint(std::ostream &os) const { ; }
|
||||||
|
};
|
||||||
|
class ActionItem : public LLVMIRItemBase {
|
||||||
|
public:
|
||||||
|
void RecursivePrint(std::ostream &os) const { ; }
|
||||||
|
};
|
||||||
|
class JMPActionItem : public ActionItem {
|
||||||
|
std::string label;
|
||||||
|
public:
|
||||||
|
void RecursivePrint(std::ostream &os) const { ; }
|
||||||
|
};
|
||||||
|
class BRAction: public JMPActionItem {
|
||||||
|
std::string cond;
|
||||||
|
std::string true_label;
|
||||||
|
std::string false_label;
|
||||||
|
public:
|
||||||
|
void RecursivePrint(std::ostream &os) const { ; }
|
||||||
|
};
|
||||||
|
class UNConditionJMPAction: public JMPActionItem {
|
||||||
|
std::string label;
|
||||||
|
public:
|
||||||
|
void RecursivePrint(std::ostream &os) const { ; }
|
||||||
|
};
|
||||||
|
class RETAction : public JMPActionItem {
|
||||||
|
std::string value;
|
||||||
|
public:
|
||||||
|
void RecursivePrint(std::ostream &os) const { ; }
|
||||||
|
};
|
||||||
|
class BinaryOperationAction : public ActionItem {
|
||||||
|
std::string op;
|
||||||
|
std::string lhs;
|
||||||
|
std::string rhs;
|
||||||
|
std::string result;
|
||||||
|
LLVMType type;
|
||||||
|
public:
|
||||||
|
void RecursivePrint(std::ostream &os) const { ; }
|
||||||
|
};
|
||||||
|
class AllocaAction : public ActionItem {
|
||||||
|
std::string name;
|
||||||
|
LLVMType type;
|
||||||
|
size_t num;
|
||||||
|
public:
|
||||||
|
void RecursivePrint(std::ostream &os) const { ; }
|
||||||
|
};
|
||||||
|
class LoadAction : public ActionItem {
|
||||||
|
std::string result;
|
||||||
|
LLVMType ty;
|
||||||
|
std::string ptr;
|
||||||
|
public:
|
||||||
|
void RecursivePrint(std::ostream &os) const { ; }
|
||||||
|
};
|
||||||
|
class StoreAction : public ActionItem {
|
||||||
|
LLVMType ty;
|
||||||
|
std::string value;
|
||||||
|
std::string ptr;
|
||||||
|
public:
|
||||||
|
void RecursivePrint(std::ostream &os) const { ; }
|
||||||
|
};
|
||||||
|
class GetElementPtrAction : public ActionItem {
|
||||||
|
std::string result;
|
||||||
|
LLVMType ty;
|
||||||
|
std::string ptr;
|
||||||
|
std::vector<std::string> indices;
|
||||||
|
public:
|
||||||
|
void RecursivePrint(std::ostream &os) const { ; }
|
||||||
|
};
|
||||||
|
class ICMPAction : public ActionItem {
|
||||||
|
std::string op;
|
||||||
|
std::string lhs;
|
||||||
|
std::string rhs;
|
||||||
|
std::string result;
|
||||||
|
LLVMType ty;
|
||||||
|
public:
|
||||||
|
void RecursivePrint(std::ostream &os) const { ; }
|
||||||
|
};
|
||||||
|
class BlockItem : public LLVMIRItemBase {
|
||||||
|
std::string label;
|
||||||
|
std::vector<std::shared_ptr<ActionItem>> actions;
|
||||||
|
std::shared_ptr<JMPActionItem> exit_action;
|
||||||
|
public:
|
||||||
|
void RecursivePrint(std::ostream &os) const { ; }
|
||||||
|
};
|
||||||
|
class FunctionDefItem : public LLVMIRItemBase {
|
||||||
|
std::vector<std::shared_ptr<BlockItem>> basic_blocks;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void RecursivePrint(std::ostream &os) const {
|
||||||
|
for (auto &item : basic_blocks) {
|
||||||
|
item->RecursivePrint(os);
|
||||||
|
os << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class ModuleItem : public LLVMIRItemBase {
|
||||||
|
std::vector<std::shared_ptr<TypeDefItem>> type_defs;
|
||||||
|
std::vector<std::shared_ptr<GlobalVarDefItem>> global_var_defs;
|
||||||
|
std::vector<std::shared_ptr<FunctionDefItem>> function_defs;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void RecursivePrint(std::ostream &os) const {
|
||||||
|
for (auto &item : type_defs) {
|
||||||
|
item->RecursivePrint(os);
|
||||||
|
os << '\n';
|
||||||
|
}
|
||||||
|
for (auto &item : global_var_defs) {
|
||||||
|
item->RecursivePrint(os);
|
||||||
|
os << '\n';
|
||||||
|
}
|
||||||
|
for (auto &item : function_defs) {
|
||||||
|
item->RecursivePrint(os);
|
||||||
|
os << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
@ -2,6 +2,7 @@
|
|||||||
#define AST_H
|
#define AST_H
|
||||||
#include "astnode.h"
|
#include "astnode.h"
|
||||||
#include "astnode_visitor.h"
|
#include "astnode_visitor.h"
|
||||||
|
#include "semantic_visitor.h"
|
||||||
#include "expr_astnode.h"
|
#include "expr_astnode.h"
|
||||||
#include "statement_astnode.h"
|
#include "statement_astnode.h"
|
||||||
#include "structural_astnode.h"
|
#include "structural_astnode.h"
|
||||||
|
@ -54,67 +54,4 @@ class ASTNodeVirturalVisitor : public ASTNodeVisitorBase {
|
|||||||
virtual void ActuralVisit(ConstantExpr_ASTNode *node) = 0;
|
virtual void ActuralVisit(ConstantExpr_ASTNode *node) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ASTSemanticCheckVisitor : public ASTNodeVirturalVisitor {
|
|
||||||
bool is_in_func_def;
|
|
||||||
bool has_return;
|
|
||||||
FunctionSchema cur_func_schema;
|
|
||||||
std::string cur_class_name;
|
|
||||||
bool is_in_class_def;
|
|
||||||
size_t loop_level;
|
|
||||||
std::shared_ptr<GlobalScope> global_scope;
|
|
||||||
friend std::shared_ptr<Program_ASTNode> CheckAndDecorate(std::shared_ptr<Program_ASTNode> src);
|
|
||||||
|
|
||||||
bool ClassExists(const std::string &name) {
|
|
||||||
if (name == "int" || name == "bool") return true;
|
|
||||||
return global_scope->classes.find(name) != global_scope->classes.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
ASTSemanticCheckVisitor() : is_in_func_def(false), loop_level(0) {}
|
|
||||||
// Structural AST Nodes
|
|
||||||
void ActuralVisit(FuncDef_ASTNode *node) override;
|
|
||||||
void ActuralVisit(ClassDef_ASTNode *node) override;
|
|
||||||
void ActuralVisit(Program_ASTNode *node) override;
|
|
||||||
|
|
||||||
// Statement AST Nodes
|
|
||||||
void ActuralVisit(EmptyStatement_ASTNode *node) override;
|
|
||||||
void ActuralVisit(DefinitionStatement_ASTNode *node) override;
|
|
||||||
void ActuralVisit(ExprStatement_ASTNode *node) override;
|
|
||||||
void ActuralVisit(IfStatement_ASTNode *node) override;
|
|
||||||
void ActuralVisit(WhileStatement_ASTNode *node) override;
|
|
||||||
void ActuralVisit(ForStatement_ASTNode *node) override;
|
|
||||||
void ActuralVisit(JmpStatement_ASTNode *node) override;
|
|
||||||
void ActuralVisit(SuiteStatement_ASTNode *node) override;
|
|
||||||
|
|
||||||
// Expression AST Nodes
|
|
||||||
void ActuralVisit(NewArrayExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(NewConstructExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(NewExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(AccessExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(IndexExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(SuffixExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(PrefixExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(OppositeExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(LNotExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(BNotExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(MDMExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(PMExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(RLExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(GGLLExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(NEExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(BAndExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(BXorExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(BOrExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(LAndExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(LOrExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(TernaryExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(AssignExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(ThisExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(ParenExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(IDExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(FunctionCallExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(FormattedStringExpr_ASTNode *node) override;
|
|
||||||
void ActuralVisit(ConstantExpr_ASTNode *node) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // ASTNODE_ActuralVisitOR_H
|
#endif // ASTNODE_ActuralVisitOR_H
|
@ -17,6 +17,7 @@ class ScopeBase {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
ScopeBase *parent; // cannot use std::shared_ptr<ScopeBase> because of circular dependency
|
ScopeBase *parent; // cannot use std::shared_ptr<ScopeBase> because of circular dependency
|
||||||
|
size_t scope_id;
|
||||||
virtual bool VariableNameAvailable(const std::string &name, int ttl) = 0;
|
virtual bool VariableNameAvailable(const std::string &name, int ttl) = 0;
|
||||||
virtual bool add_variable(const std::string &name, const ExprTypeInfo &type) = 0;
|
virtual bool add_variable(const std::string &name, const ExprTypeInfo &type) = 0;
|
||||||
virtual ExprTypeInfo fetch_varaible(const std::string &name) = 0;
|
virtual ExprTypeInfo fetch_varaible(const std::string &name) = 0;
|
||||||
@ -26,6 +27,11 @@ class ScopeBase {
|
|||||||
"for", "while", "break", "continue", "return"};
|
"for", "while", "break", "continue", "return"};
|
||||||
return keywords.find(name) != keywords.end();
|
return keywords.find(name) != keywords.end();
|
||||||
}
|
}
|
||||||
|
public:
|
||||||
|
ScopeBase() {
|
||||||
|
static size_t scope_counter=0;
|
||||||
|
scope_id = scope_counter++;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
class LocalScope : public ScopeBase {
|
class LocalScope : public ScopeBase {
|
||||||
friend class Visitor;
|
friend class Visitor;
|
||||||
@ -104,6 +110,7 @@ class ClassDefScope : public ScopeBase {
|
|||||||
friend std::shared_ptr<Program_ASTNode> CheckAndDecorate(std::shared_ptr<Program_ASTNode> src);
|
friend std::shared_ptr<Program_ASTNode> CheckAndDecorate(std::shared_ptr<Program_ASTNode> src);
|
||||||
std::unordered_map<std::string, ExprTypeInfo> member_variables;
|
std::unordered_map<std::string, ExprTypeInfo> member_variables;
|
||||||
std::unordered_map<std::string, std::shared_ptr<FunctionScope>> member_functions;
|
std::unordered_map<std::string, std::shared_ptr<FunctionScope>> member_functions;
|
||||||
|
IRClassInfo llvm_class_info;
|
||||||
bool add_variable(const std::string &name, const ExprTypeInfo &type) override {
|
bool add_variable(const std::string &name, const ExprTypeInfo &type) override {
|
||||||
if (!VariableNameAvailable(name, 0)) {
|
if (!VariableNameAvailable(name, 0)) {
|
||||||
return false;
|
return false;
|
||||||
|
69
include/ast/semantic_visitor.h
Normal file
69
include/ast/semantic_visitor.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "astnode.h"
|
||||||
|
#include "expr_astnode.h"
|
||||||
|
#include "statement_astnode.h"
|
||||||
|
#include "structural_astnode.h"
|
||||||
|
#include "astnode_visitor.h"
|
||||||
|
|
||||||
|
class ASTSemanticCheckVisitor : public ASTNodeVirturalVisitor {
|
||||||
|
bool is_in_func_def;
|
||||||
|
bool has_return;
|
||||||
|
FunctionSchema cur_func_schema;
|
||||||
|
std::string cur_class_name;
|
||||||
|
bool is_in_class_def;
|
||||||
|
size_t loop_level;
|
||||||
|
std::shared_ptr<GlobalScope> global_scope;
|
||||||
|
friend std::shared_ptr<Program_ASTNode> CheckAndDecorate(std::shared_ptr<Program_ASTNode> src);
|
||||||
|
|
||||||
|
bool ClassExists(const std::string &name) {
|
||||||
|
if (name == "int" || name == "bool") return true;
|
||||||
|
return global_scope->classes.find(name) != global_scope->classes.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
ASTSemanticCheckVisitor() : is_in_func_def(false), loop_level(0) {}
|
||||||
|
// Structural AST Nodes
|
||||||
|
void ActuralVisit(FuncDef_ASTNode *node) override;
|
||||||
|
void ActuralVisit(ClassDef_ASTNode *node) override;
|
||||||
|
void ActuralVisit(Program_ASTNode *node) override;
|
||||||
|
|
||||||
|
// Statement AST Nodes
|
||||||
|
void ActuralVisit(EmptyStatement_ASTNode *node) override;
|
||||||
|
void ActuralVisit(DefinitionStatement_ASTNode *node) override;
|
||||||
|
void ActuralVisit(ExprStatement_ASTNode *node) override;
|
||||||
|
void ActuralVisit(IfStatement_ASTNode *node) override;
|
||||||
|
void ActuralVisit(WhileStatement_ASTNode *node) override;
|
||||||
|
void ActuralVisit(ForStatement_ASTNode *node) override;
|
||||||
|
void ActuralVisit(JmpStatement_ASTNode *node) override;
|
||||||
|
void ActuralVisit(SuiteStatement_ASTNode *node) override;
|
||||||
|
|
||||||
|
// Expression AST Nodes
|
||||||
|
void ActuralVisit(NewArrayExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(NewConstructExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(NewExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(AccessExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(IndexExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(SuffixExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(PrefixExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(OppositeExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(LNotExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(BNotExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(MDMExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(PMExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(RLExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(GGLLExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(NEExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(BAndExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(BXorExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(BOrExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(LAndExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(LOrExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(TernaryExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(AssignExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(ThisExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(ParenExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(IDExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(FunctionCallExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(FormattedStringExpr_ASTNode *node) override;
|
||||||
|
void ActuralVisit(ConstantExpr_ASTNode *node) override;
|
||||||
|
};
|
@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <unordered_map>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
enum class ASTNodeType {
|
enum class ASTNodeType {
|
||||||
// Expression nodes
|
// Expression nodes
|
||||||
NewArrayExpr,
|
NewArrayExpr,
|
||||||
@ -99,3 +101,37 @@ inline bool operator==(const ExprTypeInfo &l, const ExprTypeInfo &r) {
|
|||||||
throw std::runtime_error("something strange happened");
|
throw std::runtime_error("something strange happened");
|
||||||
}
|
}
|
||||||
inline bool operator!=(const ExprTypeInfo &l, const ExprTypeInfo &r) { return !(l == r); }
|
inline bool operator!=(const ExprTypeInfo &l, const ExprTypeInfo &r) { return !(l == r); }
|
||||||
|
|
||||||
|
class IRClassInfo {
|
||||||
|
public:
|
||||||
|
std::string class_name; // This data must be provided by user
|
||||||
|
std::vector<size_t> member_var_size; // This data must be provided by user. Each of them is the size of a member
|
||||||
|
// variable, which must be in [1,4]
|
||||||
|
std::unordered_map<std::string, size_t> member_var_offset; // This data must be provided by user
|
||||||
|
std::vector<size_t> member_var_pos_after_align;
|
||||||
|
size_t class_size_after_align;
|
||||||
|
void ArrangeSpace() {
|
||||||
|
size_t cur_pos = 0;
|
||||||
|
size_t align_size = 1;
|
||||||
|
for (size_t cur_size : member_var_size) {
|
||||||
|
if (cur_size != 1 && cur_size != 4) throw std::runtime_error("Invalid member variable size");
|
||||||
|
if (cur_pos % cur_size == 0) {
|
||||||
|
member_var_pos_after_align.push_back(cur_pos);
|
||||||
|
cur_pos += cur_size;
|
||||||
|
} else {
|
||||||
|
cur_pos += cur_size - (cur_pos % cur_size);
|
||||||
|
member_var_pos_after_align.push_back(cur_pos);
|
||||||
|
cur_pos += cur_size;
|
||||||
|
}
|
||||||
|
if (cur_size > align_size) align_size = cur_size;
|
||||||
|
if (cur_pos % align_size != 0) cur_pos += align_size - (cur_pos % align_size);
|
||||||
|
class_size_after_align = cur_pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class IRVariableInfo {
|
||||||
|
public:
|
||||||
|
enum class VariableType { global_variable, local_variable, member_variable };
|
||||||
|
std::string class_name;
|
||||||
|
std::string variable_name;
|
||||||
|
};
|
@ -1,7 +1,8 @@
|
|||||||
add_subdirectory(ast)
|
add_subdirectory(ast)
|
||||||
add_subdirectory(semantic)
|
add_subdirectory(semantic)
|
||||||
|
add_subdirectory(IR)
|
||||||
add_executable(zmxcc main.cpp)
|
add_executable(zmxcc main.cpp)
|
||||||
target_link_libraries(zmxcc semantic argparse)
|
target_link_libraries(zmxcc semantic argparse IR)
|
||||||
set_target_properties(zmxcc PROPERTIES
|
set_target_properties(zmxcc PROPERTIES
|
||||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||||
)
|
)
|
5
src/IR/CMakeLists.txt
Normal file
5
src/IR/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
include_directories(${CMAKE_SOURCE_DIR}/include/IR)
|
||||||
|
file(GLOB IR_SOURCES "*.cpp")
|
||||||
|
|
||||||
|
add_library(IR STATIC ${IR_SOURCES})
|
||||||
|
target_link_libraries(IR PUBLIC ast)
|
167
src/IR/IRBuilder.cpp
Normal file
167
src/IR/IRBuilder.cpp
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
#include "IRBuilder.h"
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
// Structural AST Nodes
|
||||||
|
void IRBuilder::ActuralVisit(FuncDef_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(ClassDef_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(Program_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
throw std::runtime_error("IRBuilder not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Statement AST Nodes
|
||||||
|
void IRBuilder::ActuralVisit(EmptyStatement_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(DefinitionStatement_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(ExprStatement_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(IfStatement_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(WhileStatement_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(ForStatement_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(JmpStatement_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(SuiteStatement_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expression AST Nodes
|
||||||
|
void IRBuilder::ActuralVisit(NewArrayExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(NewConstructExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(NewExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(AccessExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(IndexExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(SuffixExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(PrefixExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(OppositeExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(LNotExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(BNotExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(MDMExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(PMExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(RLExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(GGLLExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(NEExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(BAndExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(BXorExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(BOrExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(LAndExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(LOrExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(TernaryExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(AssignExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(ThisExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(ParenExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(IDExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(FunctionCallExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(FormattedStringExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRBuilder::ActuralVisit(ConstantExpr_ASTNode *node) {
|
||||||
|
// TODO: Implement function body
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ModuleItem> BuildIR(std::shared_ptr<Program_ASTNode> src) {
|
||||||
|
IRBuilder visitor;
|
||||||
|
visitor.visit(src.get());
|
||||||
|
}
|
10
src/IR/build.sh
Executable file
10
src/IR/build.sh
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Get the directory of the script
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
|
# Change to the script directory
|
||||||
|
cd "$SCRIPT_DIR"
|
||||||
|
clang-18 -S -emit-llvm --target=riscv32-unknown-elf -O2 -fno-builtin-printf -fno-builtin-memcpy \
|
||||||
|
builtin.c -o builtin_intermediate.ll
|
||||||
|
sed 's/_builtin_/.builtin./g;s/string_/string./g;s/array_/array./g' builtin_intermediate.ll > builtin.ll
|
||||||
|
rm builtin_intermediate.ll
|
||||||
|
llc-18 -march=riscv32 builtin.ll -o builtin.s -O2
|
130
src/IR/builtin.c
Normal file
130
src/IR/builtin.c
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
#include <stdarg.h>
|
||||||
|
#define bool _Bool
|
||||||
|
#define EOF (-1)
|
||||||
|
// libc function
|
||||||
|
void* malloc(unsigned int size);
|
||||||
|
void free(void* ptr);
|
||||||
|
int printf(const char *pattern, ...);
|
||||||
|
int scanf(const char *format, ...);
|
||||||
|
int sprintf(char *str, const char *pattern, ...);
|
||||||
|
int sscanf(const char *str, const char *pattern, ...);
|
||||||
|
int string_length(char *self) {
|
||||||
|
int res=0;
|
||||||
|
while(self[res]!='\0') {
|
||||||
|
res++;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
char* string_substring(char *self,int left, int right) {
|
||||||
|
int len = right - left;
|
||||||
|
char *res = (char*)malloc(len+1);
|
||||||
|
for(int i=0;i<len;i++) {
|
||||||
|
res[i] = self[left+i];
|
||||||
|
}
|
||||||
|
res[len] = '\0';
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
int string_parseInt(char *self) {
|
||||||
|
int res;
|
||||||
|
sscanf(self, "%d", &res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
int string_ord(char *self, int index) {
|
||||||
|
return self[index];
|
||||||
|
}
|
||||||
|
void print(char *str) {
|
||||||
|
printf("%s", str);
|
||||||
|
}
|
||||||
|
void println(char *str) {
|
||||||
|
printf("%s\n", str);
|
||||||
|
}
|
||||||
|
void printInt(int n) {
|
||||||
|
printf("%d", n);
|
||||||
|
}
|
||||||
|
void printlnInt(int n) {
|
||||||
|
printf("%d\n", n);
|
||||||
|
}
|
||||||
|
char* toString(int n) {
|
||||||
|
char *res = (char*)malloc(15);
|
||||||
|
sprintf(res, "%d", n);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
char* getString() { // same as getline
|
||||||
|
char *res=(char*)malloc(11);
|
||||||
|
int allocated_length = 10;
|
||||||
|
int cur_length = 0;
|
||||||
|
char ch;
|
||||||
|
while(scanf("%c",&ch)==1) {
|
||||||
|
if(ch=='\n'||ch=='\r') break;
|
||||||
|
if(cur_length==allocated_length) {
|
||||||
|
char *new_res = (char*)malloc(allocated_length*2+1);
|
||||||
|
for(int i=0;i<allocated_length;i++) {
|
||||||
|
new_res[i] = res[i];
|
||||||
|
}
|
||||||
|
free(res);
|
||||||
|
res = new_res;
|
||||||
|
allocated_length *= 2;
|
||||||
|
}
|
||||||
|
res[cur_length++] = ch;
|
||||||
|
}
|
||||||
|
res[cur_length] = '\0';
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
int getInt() {
|
||||||
|
int res;
|
||||||
|
scanf("%d", &res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* _builtin_AllocateClassBody(int size) {
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int _builtin_GetArrayLength(void* array) {
|
||||||
|
int res=0;
|
||||||
|
array=((char*)array)-4;
|
||||||
|
res|=(((unsigned char*)array)[0]);
|
||||||
|
res|=((unsigned int)(((unsigned char*)array)[1])<<8);
|
||||||
|
res|=((unsigned int)(((unsigned char*)array)[2])<<16);
|
||||||
|
res|=((unsigned int)(((unsigned char*)array)[3])<<24);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
void* _builtin_RecursiveAllocateArray(int dims_with_size, int element_size, int* dim_size) {
|
||||||
|
void* res;
|
||||||
|
if(dims_with_size==1) {
|
||||||
|
res=malloc(dim_size[0]*element_size+4);
|
||||||
|
((unsigned char*)res)[0] = dim_size[0]&0xff;
|
||||||
|
((unsigned char*)res)[1] = (dim_size[0]>>8)&0xff;
|
||||||
|
((unsigned char*)res)[2] = (dim_size[0]>>16)&0xff;
|
||||||
|
((unsigned char*)res)[3] = (dim_size[0]>>24)&0xff;
|
||||||
|
void* actual_space=((char*)res)+4;
|
||||||
|
res=actual_space;
|
||||||
|
} else {
|
||||||
|
res=malloc(dim_size[0]*sizeof(void*)+4);
|
||||||
|
((unsigned char*)res)[0] = dim_size[0]&0xff;
|
||||||
|
((unsigned char*)res)[1] = (dim_size[0]>>8)&0xff;
|
||||||
|
((unsigned char*)res)[2] = (dim_size[0]>>16)&0xff;
|
||||||
|
((unsigned char*)res)[3] = (dim_size[0]>>24)&0xff;
|
||||||
|
void* actual_space=((char*)res)+4;
|
||||||
|
for(int i=0;i<dim_size[0];i++) {
|
||||||
|
((void**)actual_space)[i] = _builtin_RecursiveAllocateArray(dims_with_size-1, element_size, dim_size+1);
|
||||||
|
}
|
||||||
|
res=actual_space;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
// void* _builtin_AllocateArray(int total_dimensions,int basic_element_size,...) {
|
||||||
|
// va_list args;
|
||||||
|
// va_start(args, basic_element_size);
|
||||||
|
// int* dim_size=(int*)malloc(total_dimensions*sizeof(int));
|
||||||
|
// int dims_with_size=0;
|
||||||
|
// for(int i=0;i<total_dimensions;i++) {
|
||||||
|
// dim_size[i] = va_arg(args, int);
|
||||||
|
// if(dim_size[i]>=0) dims_with_size++;
|
||||||
|
// }
|
||||||
|
// if(dims_with_size<total_dimensions) basic_element_size = sizeof(void*);
|
||||||
|
// va_end(args);
|
||||||
|
// void* res=_builtin_RecursiveAllocateArray(dims_with_size, basic_element_size, dim_size);
|
||||||
|
// free(dim_size);
|
||||||
|
// return res;
|
||||||
|
// }
|
327
src/IR/builtin.ll
Normal file
327
src/IR/builtin.ll
Normal file
@ -0,0 +1,327 @@
|
|||||||
|
; ModuleID = 'builtin.c'
|
||||||
|
source_filename = "builtin.c"
|
||||||
|
target datalayout = "e-m:e-p:32:32-i64:64-n32-S128"
|
||||||
|
target triple = "riscv32-unknown-unknown-elf"
|
||||||
|
|
||||||
|
@.str = private unnamed_addr constant [3 x i8] c"%d\00", align 1
|
||||||
|
@.str.1 = private unnamed_addr constant [3 x i8] c"%s\00", align 1
|
||||||
|
@.str.2 = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1
|
||||||
|
@.str.3 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
|
||||||
|
@.str.4 = private unnamed_addr constant [3 x i8] c"%c\00", align 1
|
||||||
|
|
||||||
|
; Function Attrs: nofree norecurse nosync nounwind memory(argmem: read)
|
||||||
|
define dso_local i32 @string.length(ptr nocapture noundef readonly %0) local_unnamed_addr #0 {
|
||||||
|
br label %2
|
||||||
|
|
||||||
|
2: ; preds = %2, %1
|
||||||
|
%3 = phi i32 [ 0, %1 ], [ %7, %2 ]
|
||||||
|
%4 = getelementptr inbounds i8, ptr %0, i32 %3
|
||||||
|
%5 = load i8, ptr %4, align 1, !tbaa !6
|
||||||
|
%6 = icmp eq i8 %5, 0
|
||||||
|
%7 = add nuw nsw i32 %3, 1
|
||||||
|
br i1 %6, label %8, label %2, !llvm.loop !9
|
||||||
|
|
||||||
|
8: ; preds = %2
|
||||||
|
ret i32 %3
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
|
||||||
|
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1
|
||||||
|
|
||||||
|
; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
|
||||||
|
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1
|
||||||
|
|
||||||
|
; Function Attrs: nofree nounwind memory(write, argmem: read, inaccessiblemem: readwrite)
|
||||||
|
define dso_local noalias noundef ptr @string.substring(ptr nocapture noundef readonly %0, i32 noundef %1, i32 noundef %2) local_unnamed_addr #2 {
|
||||||
|
%4 = sub nsw i32 %2, %1
|
||||||
|
%5 = add nsw i32 %4, 1
|
||||||
|
%6 = tail call ptr @malloc(i32 noundef %5) #10
|
||||||
|
%7 = getelementptr i8, ptr %0, i32 %1
|
||||||
|
%8 = icmp sgt i32 %4, 0
|
||||||
|
br i1 %8, label %11, label %9
|
||||||
|
|
||||||
|
9: ; preds = %11, %3
|
||||||
|
%10 = getelementptr inbounds i8, ptr %6, i32 %4
|
||||||
|
store i8 0, ptr %10, align 1, !tbaa !6
|
||||||
|
ret ptr %6
|
||||||
|
|
||||||
|
11: ; preds = %3, %11
|
||||||
|
%12 = phi i32 [ %16, %11 ], [ 0, %3 ]
|
||||||
|
%13 = getelementptr i8, ptr %7, i32 %12
|
||||||
|
%14 = load i8, ptr %13, align 1, !tbaa !6
|
||||||
|
%15 = getelementptr inbounds i8, ptr %6, i32 %12
|
||||||
|
store i8 %14, ptr %15, align 1, !tbaa !6
|
||||||
|
%16 = add nuw nsw i32 %12, 1
|
||||||
|
%17 = icmp eq i32 %16, %4
|
||||||
|
br i1 %17, label %9, label %11, !llvm.loop !11
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite)
|
||||||
|
declare dso_local noalias noundef ptr @malloc(i32 noundef) local_unnamed_addr #3
|
||||||
|
|
||||||
|
; Function Attrs: nofree nounwind
|
||||||
|
define dso_local i32 @string.parseInt(ptr nocapture noundef readonly %0) local_unnamed_addr #4 {
|
||||||
|
%2 = alloca i32, align 4
|
||||||
|
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %2) #11
|
||||||
|
%3 = call i32 (ptr, ptr, ...) @sscanf(ptr noundef %0, ptr noundef nonnull @.str, ptr noundef nonnull %2) #12
|
||||||
|
%4 = load i32, ptr %2, align 4, !tbaa !12
|
||||||
|
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %2) #11
|
||||||
|
ret i32 %4
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: nofree nounwind
|
||||||
|
declare dso_local noundef i32 @sscanf(ptr nocapture noundef readonly, ptr nocapture noundef readonly, ...) local_unnamed_addr #4
|
||||||
|
|
||||||
|
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
|
||||||
|
define dso_local i32 @string.ord(ptr nocapture noundef readonly %0, i32 noundef %1) local_unnamed_addr #5 {
|
||||||
|
%3 = getelementptr inbounds i8, ptr %0, i32 %1
|
||||||
|
%4 = load i8, ptr %3, align 1, !tbaa !6
|
||||||
|
%5 = zext i8 %4 to i32
|
||||||
|
ret i32 %5
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: nounwind
|
||||||
|
define dso_local void @print(ptr noundef %0) local_unnamed_addr #6 {
|
||||||
|
%2 = tail call i32 (ptr, ...) @printf(ptr noundef nonnull @.str.1, ptr noundef %0) #13
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare dso_local i32 @printf(ptr noundef, ...) local_unnamed_addr #7
|
||||||
|
|
||||||
|
; Function Attrs: nounwind
|
||||||
|
define dso_local void @println(ptr noundef %0) local_unnamed_addr #6 {
|
||||||
|
%2 = tail call i32 (ptr, ...) @printf(ptr noundef nonnull @.str.2, ptr noundef %0) #13
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: nounwind
|
||||||
|
define dso_local void @printInt(i32 noundef %0) local_unnamed_addr #6 {
|
||||||
|
%2 = tail call i32 (ptr, ...) @printf(ptr noundef nonnull @.str, i32 noundef %0) #13
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: nounwind
|
||||||
|
define dso_local void @printlnInt(i32 noundef %0) local_unnamed_addr #6 {
|
||||||
|
%2 = tail call i32 (ptr, ...) @printf(ptr noundef nonnull @.str.3, i32 noundef %0) #13
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: nofree nounwind
|
||||||
|
define dso_local noalias noundef ptr @toString(i32 noundef %0) local_unnamed_addr #4 {
|
||||||
|
%2 = tail call dereferenceable_or_null(15) ptr @malloc(i32 noundef 15) #10
|
||||||
|
%3 = tail call i32 (ptr, ptr, ...) @sprintf(ptr noundef nonnull dereferenceable(1) %2, ptr noundef nonnull dereferenceable(1) @.str, i32 noundef %0) #12
|
||||||
|
ret ptr %2
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: nofree nounwind
|
||||||
|
declare dso_local noundef i32 @sprintf(ptr noalias nocapture noundef writeonly, ptr nocapture noundef readonly, ...) local_unnamed_addr #4
|
||||||
|
|
||||||
|
; Function Attrs: nounwind
|
||||||
|
define dso_local noalias ptr @getString() local_unnamed_addr #6 {
|
||||||
|
%1 = alloca i8, align 1
|
||||||
|
%2 = tail call dereferenceable_or_null(11) ptr @malloc(i32 noundef 11) #10
|
||||||
|
call void @llvm.lifetime.start.p0(i64 1, ptr nonnull %1) #11
|
||||||
|
%3 = call i32 (ptr, ...) @scanf(ptr noundef nonnull @.str.4, ptr noundef nonnull %1) #12
|
||||||
|
%4 = icmp eq i32 %3, 1
|
||||||
|
br i1 %4, label %5, label %34
|
||||||
|
|
||||||
|
5: ; preds = %0, %26
|
||||||
|
%6 = phi ptr [ %29, %26 ], [ %2, %0 ]
|
||||||
|
%7 = phi i32 [ %30, %26 ], [ 0, %0 ]
|
||||||
|
%8 = phi i32 [ %28, %26 ], [ 10, %0 ]
|
||||||
|
%9 = load i8, ptr %1, align 1
|
||||||
|
switch i8 %9, label %10 [
|
||||||
|
i8 13, label %34
|
||||||
|
i8 10, label %34
|
||||||
|
]
|
||||||
|
|
||||||
|
10: ; preds = %5
|
||||||
|
%11 = icmp eq i32 %7, %8
|
||||||
|
br i1 %11, label %12, label %26
|
||||||
|
|
||||||
|
12: ; preds = %10
|
||||||
|
%13 = shl nuw nsw i32 %7, 1
|
||||||
|
%14 = or disjoint i32 %13, 1
|
||||||
|
%15 = call ptr @malloc(i32 noundef %14) #10
|
||||||
|
%16 = icmp eq i32 %7, 0
|
||||||
|
br i1 %16, label %17, label %19
|
||||||
|
|
||||||
|
17: ; preds = %19, %12
|
||||||
|
call void @free(ptr noundef %6) #12
|
||||||
|
%18 = load i8, ptr %1, align 1, !tbaa !6
|
||||||
|
br label %26
|
||||||
|
|
||||||
|
19: ; preds = %12, %19
|
||||||
|
%20 = phi i32 [ %24, %19 ], [ 0, %12 ]
|
||||||
|
%21 = getelementptr inbounds i8, ptr %6, i32 %20
|
||||||
|
%22 = load i8, ptr %21, align 1, !tbaa !6
|
||||||
|
%23 = getelementptr inbounds i8, ptr %15, i32 %20
|
||||||
|
store i8 %22, ptr %23, align 1, !tbaa !6
|
||||||
|
%24 = add nuw nsw i32 %20, 1
|
||||||
|
%25 = icmp eq i32 %24, %7
|
||||||
|
br i1 %25, label %17, label %19, !llvm.loop !14
|
||||||
|
|
||||||
|
26: ; preds = %17, %10
|
||||||
|
%27 = phi i8 [ %18, %17 ], [ %9, %10 ]
|
||||||
|
%28 = phi i32 [ %13, %17 ], [ %8, %10 ]
|
||||||
|
%29 = phi ptr [ %15, %17 ], [ %6, %10 ]
|
||||||
|
%30 = add nuw nsw i32 %7, 1
|
||||||
|
%31 = getelementptr inbounds i8, ptr %29, i32 %7
|
||||||
|
store i8 %27, ptr %31, align 1, !tbaa !6
|
||||||
|
%32 = call i32 (ptr, ...) @scanf(ptr noundef nonnull @.str.4, ptr noundef nonnull %1) #12
|
||||||
|
%33 = icmp eq i32 %32, 1
|
||||||
|
br i1 %33, label %5, label %34, !llvm.loop !15
|
||||||
|
|
||||||
|
34: ; preds = %26, %5, %5, %0
|
||||||
|
%35 = phi i32 [ 0, %0 ], [ %7, %5 ], [ %7, %5 ], [ %30, %26 ]
|
||||||
|
%36 = phi ptr [ %2, %0 ], [ %6, %5 ], [ %6, %5 ], [ %29, %26 ]
|
||||||
|
%37 = getelementptr inbounds i8, ptr %36, i32 %35
|
||||||
|
store i8 0, ptr %37, align 1, !tbaa !6
|
||||||
|
call void @llvm.lifetime.end.p0(i64 1, ptr nonnull %1) #11
|
||||||
|
ret ptr %36
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: nofree nounwind
|
||||||
|
declare dso_local noundef i32 @scanf(ptr nocapture noundef readonly, ...) local_unnamed_addr #4
|
||||||
|
|
||||||
|
; Function Attrs: mustprogress nounwind willreturn allockind("free") memory(argmem: readwrite, inaccessiblemem: readwrite)
|
||||||
|
declare dso_local void @free(ptr allocptr nocapture noundef) local_unnamed_addr #8
|
||||||
|
|
||||||
|
; Function Attrs: nofree nounwind
|
||||||
|
define dso_local i32 @getInt() local_unnamed_addr #4 {
|
||||||
|
%1 = alloca i32, align 4
|
||||||
|
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %1) #11
|
||||||
|
%2 = call i32 (ptr, ...) @scanf(ptr noundef nonnull @.str, ptr noundef nonnull %1) #12
|
||||||
|
%3 = load i32, ptr %1, align 4, !tbaa !12
|
||||||
|
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %1) #11
|
||||||
|
ret i32 %3
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: mustprogress nofree nounwind willreturn memory(inaccessiblemem: readwrite)
|
||||||
|
define dso_local noalias noundef ptr @.builtin.AllocateClassBody(i32 noundef %0) local_unnamed_addr #9 {
|
||||||
|
%2 = tail call ptr @malloc(i32 noundef %0) #10
|
||||||
|
ret ptr %2
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
|
||||||
|
define dso_local i32 @.builtin.GetArrayLength(ptr nocapture noundef readonly %0) local_unnamed_addr #5 {
|
||||||
|
%2 = getelementptr inbounds i8, ptr %0, i32 -4
|
||||||
|
%3 = load i8, ptr %2, align 1, !tbaa !6
|
||||||
|
%4 = zext i8 %3 to i32
|
||||||
|
%5 = getelementptr inbounds i8, ptr %0, i32 -3
|
||||||
|
%6 = load i8, ptr %5, align 1, !tbaa !6
|
||||||
|
%7 = zext i8 %6 to i32
|
||||||
|
%8 = shl nuw nsw i32 %7, 8
|
||||||
|
%9 = or disjoint i32 %8, %4
|
||||||
|
%10 = getelementptr inbounds i8, ptr %0, i32 -2
|
||||||
|
%11 = load i8, ptr %10, align 1, !tbaa !6
|
||||||
|
%12 = zext i8 %11 to i32
|
||||||
|
%13 = shl nuw nsw i32 %12, 16
|
||||||
|
%14 = or disjoint i32 %9, %13
|
||||||
|
%15 = getelementptr inbounds i8, ptr %0, i32 -1
|
||||||
|
%16 = load i8, ptr %15, align 1, !tbaa !6
|
||||||
|
%17 = zext i8 %16 to i32
|
||||||
|
%18 = shl nuw i32 %17, 24
|
||||||
|
%19 = or disjoint i32 %14, %18
|
||||||
|
ret i32 %19
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: nofree nounwind memory(write, argmem: read, inaccessiblemem: readwrite)
|
||||||
|
define dso_local noalias nonnull ptr @.builtin.RecursiveAllocateArray(i32 noundef %0, i32 noundef %1, ptr nocapture noundef readonly %2) local_unnamed_addr #2 {
|
||||||
|
%4 = icmp eq i32 %0, 1
|
||||||
|
%5 = load i32, ptr %2, align 4, !tbaa !12
|
||||||
|
%6 = trunc i32 %5 to i8
|
||||||
|
%7 = lshr i32 %5, 8
|
||||||
|
%8 = trunc i32 %7 to i8
|
||||||
|
%9 = lshr i32 %5, 16
|
||||||
|
%10 = trunc i32 %9 to i8
|
||||||
|
%11 = lshr i32 %5, 24
|
||||||
|
%12 = trunc i32 %11 to i8
|
||||||
|
br i1 %4, label %13, label %21
|
||||||
|
|
||||||
|
13: ; preds = %3
|
||||||
|
%14 = mul nsw i32 %5, %1
|
||||||
|
%15 = add nsw i32 %14, 4
|
||||||
|
%16 = tail call ptr @malloc(i32 noundef %15) #10
|
||||||
|
store i8 %6, ptr %16, align 1, !tbaa !6
|
||||||
|
%17 = getelementptr inbounds i8, ptr %16, i32 1
|
||||||
|
store i8 %8, ptr %17, align 1, !tbaa !6
|
||||||
|
%18 = getelementptr inbounds i8, ptr %16, i32 2
|
||||||
|
store i8 %10, ptr %18, align 1, !tbaa !6
|
||||||
|
%19 = getelementptr inbounds i8, ptr %16, i32 3
|
||||||
|
store i8 %12, ptr %19, align 1, !tbaa !6
|
||||||
|
%20 = getelementptr inbounds i8, ptr %16, i32 4
|
||||||
|
br label %40
|
||||||
|
|
||||||
|
21: ; preds = %3
|
||||||
|
%22 = shl i32 %5, 2
|
||||||
|
%23 = add i32 %22, 4
|
||||||
|
%24 = tail call ptr @malloc(i32 noundef %23) #10
|
||||||
|
store i8 %6, ptr %24, align 1, !tbaa !6
|
||||||
|
%25 = getelementptr inbounds i8, ptr %24, i32 1
|
||||||
|
store i8 %8, ptr %25, align 1, !tbaa !6
|
||||||
|
%26 = getelementptr inbounds i8, ptr %24, i32 2
|
||||||
|
store i8 %10, ptr %26, align 1, !tbaa !6
|
||||||
|
%27 = getelementptr inbounds i8, ptr %24, i32 3
|
||||||
|
store i8 %12, ptr %27, align 1, !tbaa !6
|
||||||
|
%28 = getelementptr inbounds i8, ptr %24, i32 4
|
||||||
|
%29 = icmp sgt i32 %5, 0
|
||||||
|
br i1 %29, label %30, label %40
|
||||||
|
|
||||||
|
30: ; preds = %21
|
||||||
|
%31 = add nsw i32 %0, -1
|
||||||
|
%32 = getelementptr inbounds i32, ptr %2, i32 1
|
||||||
|
br label %33
|
||||||
|
|
||||||
|
33: ; preds = %30, %33
|
||||||
|
%34 = phi i32 [ 0, %30 ], [ %37, %33 ]
|
||||||
|
%35 = tail call ptr @.builtin.RecursiveAllocateArray(i32 noundef %31, i32 noundef %1, ptr noundef nonnull %32) #12
|
||||||
|
%36 = getelementptr inbounds ptr, ptr %28, i32 %34
|
||||||
|
store ptr %35, ptr %36, align 4, !tbaa !16
|
||||||
|
%37 = add nuw nsw i32 %34, 1
|
||||||
|
%38 = load i32, ptr %2, align 4, !tbaa !12
|
||||||
|
%39 = icmp slt i32 %37, %38
|
||||||
|
br i1 %39, label %33, label %40, !llvm.loop !18
|
||||||
|
|
||||||
|
40: ; preds = %33, %21, %13
|
||||||
|
%41 = phi ptr [ %20, %13 ], [ %28, %21 ], [ %28, %33 ]
|
||||||
|
ret ptr %41
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes #0 = { nofree norecurse nosync nounwind memory(argmem: read) "no-builtin-memcpy" "no-builtin-printf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic-rv32" "target-features"="+32bit,+a,+c,+m,+relax,-d,-e,-experimental-zacas,-experimental-zcmop,-experimental-zfbfmin,-experimental-zicfilp,-experimental-zicfiss,-experimental-zimop,-experimental-ztso,-experimental-zvfbfmin,-experimental-zvfbfwma,-f,-h,-smaia,-smepmp,-ssaia,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-za128rs,-za64rs,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfa,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }
|
||||||
|
attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
|
||||||
|
attributes #2 = { nofree nounwind memory(write, argmem: read, inaccessiblemem: readwrite) "no-builtin-memcpy" "no-builtin-printf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic-rv32" "target-features"="+32bit,+a,+c,+m,+relax,-d,-e,-experimental-zacas,-experimental-zcmop,-experimental-zfbfmin,-experimental-zicfilp,-experimental-zicfiss,-experimental-zimop,-experimental-ztso,-experimental-zvfbfmin,-experimental-zvfbfwma,-f,-h,-smaia,-smepmp,-ssaia,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-za128rs,-za64rs,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfa,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }
|
||||||
|
attributes #3 = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" "no-builtin-memcpy" "no-builtin-printf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic-rv32" "target-features"="+32bit,+a,+c,+m,+relax,-d,-e,-experimental-zacas,-experimental-zcmop,-experimental-zfbfmin,-experimental-zicfilp,-experimental-zicfiss,-experimental-zimop,-experimental-ztso,-experimental-zvfbfmin,-experimental-zvfbfwma,-f,-h,-smaia,-smepmp,-ssaia,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-za128rs,-za64rs,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfa,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }
|
||||||
|
attributes #4 = { nofree nounwind "no-builtin-memcpy" "no-builtin-printf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic-rv32" "target-features"="+32bit,+a,+c,+m,+relax,-d,-e,-experimental-zacas,-experimental-zcmop,-experimental-zfbfmin,-experimental-zicfilp,-experimental-zicfiss,-experimental-zimop,-experimental-ztso,-experimental-zvfbfmin,-experimental-zvfbfwma,-f,-h,-smaia,-smepmp,-ssaia,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-za128rs,-za64rs,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfa,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }
|
||||||
|
attributes #5 = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) "no-builtin-memcpy" "no-builtin-printf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic-rv32" "target-features"="+32bit,+a,+c,+m,+relax,-d,-e,-experimental-zacas,-experimental-zcmop,-experimental-zfbfmin,-experimental-zicfilp,-experimental-zicfiss,-experimental-zimop,-experimental-ztso,-experimental-zvfbfmin,-experimental-zvfbfwma,-f,-h,-smaia,-smepmp,-ssaia,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-za128rs,-za64rs,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfa,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }
|
||||||
|
attributes #6 = { nounwind "no-builtin-memcpy" "no-builtin-printf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic-rv32" "target-features"="+32bit,+a,+c,+m,+relax,-d,-e,-experimental-zacas,-experimental-zcmop,-experimental-zfbfmin,-experimental-zicfilp,-experimental-zicfiss,-experimental-zimop,-experimental-ztso,-experimental-zvfbfmin,-experimental-zvfbfwma,-f,-h,-smaia,-smepmp,-ssaia,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-za128rs,-za64rs,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfa,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }
|
||||||
|
attributes #7 = { "no-builtin-memcpy" "no-builtin-printf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic-rv32" "target-features"="+32bit,+a,+c,+m,+relax,-d,-e,-experimental-zacas,-experimental-zcmop,-experimental-zfbfmin,-experimental-zicfilp,-experimental-zicfiss,-experimental-zimop,-experimental-ztso,-experimental-zvfbfmin,-experimental-zvfbfwma,-f,-h,-smaia,-smepmp,-ssaia,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-za128rs,-za64rs,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfa,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }
|
||||||
|
attributes #8 = { mustprogress nounwind willreturn allockind("free") memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" "no-builtin-memcpy" "no-builtin-printf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic-rv32" "target-features"="+32bit,+a,+c,+m,+relax,-d,-e,-experimental-zacas,-experimental-zcmop,-experimental-zfbfmin,-experimental-zicfilp,-experimental-zicfiss,-experimental-zimop,-experimental-ztso,-experimental-zvfbfmin,-experimental-zvfbfwma,-f,-h,-smaia,-smepmp,-ssaia,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-za128rs,-za64rs,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfa,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }
|
||||||
|
attributes #9 = { mustprogress nofree nounwind willreturn memory(inaccessiblemem: readwrite) "no-builtin-memcpy" "no-builtin-printf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic-rv32" "target-features"="+32bit,+a,+c,+m,+relax,-d,-e,-experimental-zacas,-experimental-zcmop,-experimental-zfbfmin,-experimental-zicfilp,-experimental-zicfiss,-experimental-zimop,-experimental-ztso,-experimental-zvfbfmin,-experimental-zvfbfwma,-f,-h,-smaia,-smepmp,-ssaia,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-za128rs,-za64rs,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfa,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }
|
||||||
|
attributes #10 = { allocsize(0) "no-builtin-memcpy" "no-builtin-printf" }
|
||||||
|
attributes #11 = { nounwind }
|
||||||
|
attributes #12 = { "no-builtin-memcpy" "no-builtin-printf" }
|
||||||
|
attributes #13 = { nobuiltin nounwind "no-builtin-memcpy" "no-builtin-printf" }
|
||||||
|
|
||||||
|
!llvm.module.flags = !{!0, !1, !2, !4}
|
||||||
|
!llvm.ident = !{!5}
|
||||||
|
|
||||||
|
!0 = !{i32 1, !"wchar_size", i32 4}
|
||||||
|
!1 = !{i32 1, !"target-abi", !"ilp32"}
|
||||||
|
!2 = !{i32 6, !"riscv-isa", !3}
|
||||||
|
!3 = !{!"rv32i2p1_m2p0_a2p1_c2p0"}
|
||||||
|
!4 = !{i32 8, !"SmallDataLimit", i32 8}
|
||||||
|
!5 = !{!"Ubuntu clang version 18.1.8 (++20240731024944+3b5b5c1ec4a3-1~exp1~20240731145000.144)"}
|
||||||
|
!6 = !{!7, !7, i64 0}
|
||||||
|
!7 = !{!"omnipotent char", !8, i64 0}
|
||||||
|
!8 = !{!"Simple C/C++ TBAA"}
|
||||||
|
!9 = distinct !{!9, !10}
|
||||||
|
!10 = !{!"llvm.loop.mustprogress"}
|
||||||
|
!11 = distinct !{!11, !10}
|
||||||
|
!12 = !{!13, !13, i64 0}
|
||||||
|
!13 = !{!"int", !7, i64 0}
|
||||||
|
!14 = distinct !{!14, !10}
|
||||||
|
!15 = distinct !{!15, !10}
|
||||||
|
!16 = !{!17, !17, i64 0}
|
||||||
|
!17 = !{!"any pointer", !7, i64 0}
|
||||||
|
!18 = distinct !{!18, !10}
|
464
src/IR/builtin.s
Normal file
464
src/IR/builtin.s
Normal file
@ -0,0 +1,464 @@
|
|||||||
|
.text
|
||||||
|
.attribute 4, 16
|
||||||
|
.attribute 5, "rv32i2p1_m2p0_a2p1_c2p0"
|
||||||
|
.file "builtin.c"
|
||||||
|
.option push
|
||||||
|
.option arch, +a, +c, +m
|
||||||
|
.globl string.length # -- Begin function string.length
|
||||||
|
.p2align 1
|
||||||
|
.type string.length,@function
|
||||||
|
string.length: # @string.length
|
||||||
|
# %bb.0:
|
||||||
|
li a1, 0
|
||||||
|
.LBB0_1: # =>This Inner Loop Header: Depth=1
|
||||||
|
add a2, a0, a1
|
||||||
|
lbu a2, 0(a2)
|
||||||
|
addi a1, a1, 1
|
||||||
|
bnez a2, .LBB0_1
|
||||||
|
# %bb.2:
|
||||||
|
addi a0, a1, -1
|
||||||
|
ret
|
||||||
|
.Lfunc_end0:
|
||||||
|
.size string.length, .Lfunc_end0-string.length
|
||||||
|
# -- End function
|
||||||
|
.option pop
|
||||||
|
.option push
|
||||||
|
.option arch, +a, +c, +m
|
||||||
|
.globl string.substring # -- Begin function string.substring
|
||||||
|
.p2align 1
|
||||||
|
.type string.substring,@function
|
||||||
|
string.substring: # @string.substring
|
||||||
|
# %bb.0:
|
||||||
|
addi sp, sp, -16
|
||||||
|
sw ra, 12(sp) # 4-byte Folded Spill
|
||||||
|
sw s0, 8(sp) # 4-byte Folded Spill
|
||||||
|
sw s1, 4(sp) # 4-byte Folded Spill
|
||||||
|
sw s2, 0(sp) # 4-byte Folded Spill
|
||||||
|
mv s0, a1
|
||||||
|
mv s2, a0
|
||||||
|
sub s1, a2, a1
|
||||||
|
addi a0, s1, 1
|
||||||
|
call malloc
|
||||||
|
add a1, a0, s1
|
||||||
|
blez s1, .LBB1_3
|
||||||
|
# %bb.1: # %.preheader
|
||||||
|
add s0, s0, s2
|
||||||
|
mv a2, a0
|
||||||
|
.LBB1_2: # =>This Inner Loop Header: Depth=1
|
||||||
|
lbu a3, 0(s0)
|
||||||
|
sb a3, 0(a2)
|
||||||
|
addi a2, a2, 1
|
||||||
|
addi s0, s0, 1
|
||||||
|
bne a2, a1, .LBB1_2
|
||||||
|
.LBB1_3:
|
||||||
|
sb zero, 0(a1)
|
||||||
|
lw ra, 12(sp) # 4-byte Folded Reload
|
||||||
|
lw s0, 8(sp) # 4-byte Folded Reload
|
||||||
|
lw s1, 4(sp) # 4-byte Folded Reload
|
||||||
|
lw s2, 0(sp) # 4-byte Folded Reload
|
||||||
|
addi sp, sp, 16
|
||||||
|
ret
|
||||||
|
.Lfunc_end1:
|
||||||
|
.size string.substring, .Lfunc_end1-string.substring
|
||||||
|
# -- End function
|
||||||
|
.option pop
|
||||||
|
.option push
|
||||||
|
.option arch, +a, +c, +m
|
||||||
|
.globl string.parseInt # -- Begin function string.parseInt
|
||||||
|
.p2align 1
|
||||||
|
.type string.parseInt,@function
|
||||||
|
string.parseInt: # @string.parseInt
|
||||||
|
# %bb.0:
|
||||||
|
addi sp, sp, -16
|
||||||
|
sw ra, 12(sp) # 4-byte Folded Spill
|
||||||
|
lui a1, %hi(.L.str)
|
||||||
|
addi a1, a1, %lo(.L.str)
|
||||||
|
addi a2, sp, 8
|
||||||
|
call sscanf
|
||||||
|
lw a0, 8(sp)
|
||||||
|
lw ra, 12(sp) # 4-byte Folded Reload
|
||||||
|
addi sp, sp, 16
|
||||||
|
ret
|
||||||
|
.Lfunc_end2:
|
||||||
|
.size string.parseInt, .Lfunc_end2-string.parseInt
|
||||||
|
# -- End function
|
||||||
|
.option pop
|
||||||
|
.option push
|
||||||
|
.option arch, +a, +c, +m
|
||||||
|
.globl string.ord # -- Begin function string.ord
|
||||||
|
.p2align 1
|
||||||
|
.type string.ord,@function
|
||||||
|
string.ord: # @string.ord
|
||||||
|
# %bb.0:
|
||||||
|
add a0, a0, a1
|
||||||
|
lbu a0, 0(a0)
|
||||||
|
ret
|
||||||
|
.Lfunc_end3:
|
||||||
|
.size string.ord, .Lfunc_end3-string.ord
|
||||||
|
# -- End function
|
||||||
|
.option pop
|
||||||
|
.option push
|
||||||
|
.option arch, +a, +c, +m
|
||||||
|
.globl print # -- Begin function print
|
||||||
|
.p2align 1
|
||||||
|
.type print,@function
|
||||||
|
print: # @print
|
||||||
|
# %bb.0:
|
||||||
|
lui a1, %hi(.L.str.1)
|
||||||
|
addi a1, a1, %lo(.L.str.1)
|
||||||
|
mv a2, a0
|
||||||
|
mv a0, a1
|
||||||
|
mv a1, a2
|
||||||
|
tail printf
|
||||||
|
.Lfunc_end4:
|
||||||
|
.size print, .Lfunc_end4-print
|
||||||
|
# -- End function
|
||||||
|
.option pop
|
||||||
|
.option push
|
||||||
|
.option arch, +a, +c, +m
|
||||||
|
.globl println # -- Begin function println
|
||||||
|
.p2align 1
|
||||||
|
.type println,@function
|
||||||
|
println: # @println
|
||||||
|
# %bb.0:
|
||||||
|
lui a1, %hi(.L.str.2)
|
||||||
|
addi a1, a1, %lo(.L.str.2)
|
||||||
|
mv a2, a0
|
||||||
|
mv a0, a1
|
||||||
|
mv a1, a2
|
||||||
|
tail printf
|
||||||
|
.Lfunc_end5:
|
||||||
|
.size println, .Lfunc_end5-println
|
||||||
|
# -- End function
|
||||||
|
.option pop
|
||||||
|
.option push
|
||||||
|
.option arch, +a, +c, +m
|
||||||
|
.globl printInt # -- Begin function printInt
|
||||||
|
.p2align 1
|
||||||
|
.type printInt,@function
|
||||||
|
printInt: # @printInt
|
||||||
|
# %bb.0:
|
||||||
|
lui a1, %hi(.L.str)
|
||||||
|
addi a1, a1, %lo(.L.str)
|
||||||
|
mv a2, a0
|
||||||
|
mv a0, a1
|
||||||
|
mv a1, a2
|
||||||
|
tail printf
|
||||||
|
.Lfunc_end6:
|
||||||
|
.size printInt, .Lfunc_end6-printInt
|
||||||
|
# -- End function
|
||||||
|
.option pop
|
||||||
|
.option push
|
||||||
|
.option arch, +a, +c, +m
|
||||||
|
.globl printlnInt # -- Begin function printlnInt
|
||||||
|
.p2align 1
|
||||||
|
.type printlnInt,@function
|
||||||
|
printlnInt: # @printlnInt
|
||||||
|
# %bb.0:
|
||||||
|
lui a1, %hi(.L.str.3)
|
||||||
|
addi a1, a1, %lo(.L.str.3)
|
||||||
|
mv a2, a0
|
||||||
|
mv a0, a1
|
||||||
|
mv a1, a2
|
||||||
|
tail printf
|
||||||
|
.Lfunc_end7:
|
||||||
|
.size printlnInt, .Lfunc_end7-printlnInt
|
||||||
|
# -- End function
|
||||||
|
.option pop
|
||||||
|
.option push
|
||||||
|
.option arch, +a, +c, +m
|
||||||
|
.globl toString # -- Begin function toString
|
||||||
|
.p2align 1
|
||||||
|
.type toString,@function
|
||||||
|
toString: # @toString
|
||||||
|
# %bb.0:
|
||||||
|
addi sp, sp, -16
|
||||||
|
sw ra, 12(sp) # 4-byte Folded Spill
|
||||||
|
sw s0, 8(sp) # 4-byte Folded Spill
|
||||||
|
sw s1, 4(sp) # 4-byte Folded Spill
|
||||||
|
mv s0, a0
|
||||||
|
li a0, 15
|
||||||
|
call malloc
|
||||||
|
mv s1, a0
|
||||||
|
lui a0, %hi(.L.str)
|
||||||
|
addi a1, a0, %lo(.L.str)
|
||||||
|
mv a0, s1
|
||||||
|
mv a2, s0
|
||||||
|
call sprintf
|
||||||
|
mv a0, s1
|
||||||
|
lw ra, 12(sp) # 4-byte Folded Reload
|
||||||
|
lw s0, 8(sp) # 4-byte Folded Reload
|
||||||
|
lw s1, 4(sp) # 4-byte Folded Reload
|
||||||
|
addi sp, sp, 16
|
||||||
|
ret
|
||||||
|
.Lfunc_end8:
|
||||||
|
.size toString, .Lfunc_end8-toString
|
||||||
|
# -- End function
|
||||||
|
.option pop
|
||||||
|
.option push
|
||||||
|
.option arch, +a, +c, +m
|
||||||
|
.globl getString # -- Begin function getString
|
||||||
|
.p2align 1
|
||||||
|
.type getString,@function
|
||||||
|
getString: # @getString
|
||||||
|
# %bb.0:
|
||||||
|
addi sp, sp, -48
|
||||||
|
sw ra, 44(sp) # 4-byte Folded Spill
|
||||||
|
sw s0, 40(sp) # 4-byte Folded Spill
|
||||||
|
sw s1, 36(sp) # 4-byte Folded Spill
|
||||||
|
sw s2, 32(sp) # 4-byte Folded Spill
|
||||||
|
sw s3, 28(sp) # 4-byte Folded Spill
|
||||||
|
sw s4, 24(sp) # 4-byte Folded Spill
|
||||||
|
sw s5, 20(sp) # 4-byte Folded Spill
|
||||||
|
sw s6, 16(sp) # 4-byte Folded Spill
|
||||||
|
sw s7, 12(sp) # 4-byte Folded Spill
|
||||||
|
sw s8, 8(sp) # 4-byte Folded Spill
|
||||||
|
li a0, 11
|
||||||
|
call malloc
|
||||||
|
mv s8, a0
|
||||||
|
lui a0, %hi(.L.str.4)
|
||||||
|
addi s2, a0, %lo(.L.str.4)
|
||||||
|
addi a1, sp, 7
|
||||||
|
mv a0, s2
|
||||||
|
call scanf
|
||||||
|
li s3, 1
|
||||||
|
bne a0, s3, .LBB9_11
|
||||||
|
# %bb.1: # %.preheader1
|
||||||
|
li s1, 0
|
||||||
|
li s4, 10
|
||||||
|
li s5, 13
|
||||||
|
mv s6, s8
|
||||||
|
li s7, 10
|
||||||
|
j .LBB9_4
|
||||||
|
.LBB9_2: # in Loop: Header=BB9_4 Depth=1
|
||||||
|
mv s8, s6
|
||||||
|
.LBB9_3: # in Loop: Header=BB9_4 Depth=1
|
||||||
|
addi s0, s1, 1
|
||||||
|
add s1, s1, s8
|
||||||
|
sb a0, 0(s1)
|
||||||
|
addi a1, sp, 7
|
||||||
|
mv a0, s2
|
||||||
|
call scanf
|
||||||
|
mv s1, s0
|
||||||
|
bne a0, s3, .LBB9_13
|
||||||
|
.LBB9_4: # =>This Loop Header: Depth=1
|
||||||
|
# Child Loop BB9_9 Depth 2
|
||||||
|
lbu a0, 7(sp)
|
||||||
|
beq a0, s4, .LBB9_12
|
||||||
|
# %bb.5: # in Loop: Header=BB9_4 Depth=1
|
||||||
|
beq a0, s5, .LBB9_12
|
||||||
|
# %bb.6: # in Loop: Header=BB9_4 Depth=1
|
||||||
|
bne s1, s7, .LBB9_2
|
||||||
|
# %bb.7: # in Loop: Header=BB9_4 Depth=1
|
||||||
|
slli s7, s1, 1
|
||||||
|
addi a0, s7, 1
|
||||||
|
call malloc
|
||||||
|
mv s8, a0
|
||||||
|
beqz s1, .LBB9_10
|
||||||
|
# %bb.8: # %.preheader
|
||||||
|
# in Loop: Header=BB9_4 Depth=1
|
||||||
|
add a0, s8, s1
|
||||||
|
mv a1, s6
|
||||||
|
mv a2, s8
|
||||||
|
.LBB9_9: # Parent Loop BB9_4 Depth=1
|
||||||
|
# => This Inner Loop Header: Depth=2
|
||||||
|
lbu a3, 0(a1)
|
||||||
|
sb a3, 0(a2)
|
||||||
|
addi a2, a2, 1
|
||||||
|
addi a1, a1, 1
|
||||||
|
bne a2, a0, .LBB9_9
|
||||||
|
.LBB9_10: # in Loop: Header=BB9_4 Depth=1
|
||||||
|
mv a0, s6
|
||||||
|
call free
|
||||||
|
lbu a0, 7(sp)
|
||||||
|
mv s6, s8
|
||||||
|
j .LBB9_3
|
||||||
|
.LBB9_11:
|
||||||
|
li s0, 0
|
||||||
|
j .LBB9_13
|
||||||
|
.LBB9_12:
|
||||||
|
mv s0, s1
|
||||||
|
mv s8, s6
|
||||||
|
.LBB9_13:
|
||||||
|
add s0, s0, s8
|
||||||
|
sb zero, 0(s0)
|
||||||
|
mv a0, s8
|
||||||
|
lw ra, 44(sp) # 4-byte Folded Reload
|
||||||
|
lw s0, 40(sp) # 4-byte Folded Reload
|
||||||
|
lw s1, 36(sp) # 4-byte Folded Reload
|
||||||
|
lw s2, 32(sp) # 4-byte Folded Reload
|
||||||
|
lw s3, 28(sp) # 4-byte Folded Reload
|
||||||
|
lw s4, 24(sp) # 4-byte Folded Reload
|
||||||
|
lw s5, 20(sp) # 4-byte Folded Reload
|
||||||
|
lw s6, 16(sp) # 4-byte Folded Reload
|
||||||
|
lw s7, 12(sp) # 4-byte Folded Reload
|
||||||
|
lw s8, 8(sp) # 4-byte Folded Reload
|
||||||
|
addi sp, sp, 48
|
||||||
|
ret
|
||||||
|
.Lfunc_end9:
|
||||||
|
.size getString, .Lfunc_end9-getString
|
||||||
|
# -- End function
|
||||||
|
.option pop
|
||||||
|
.option push
|
||||||
|
.option arch, +a, +c, +m
|
||||||
|
.globl getInt # -- Begin function getInt
|
||||||
|
.p2align 1
|
||||||
|
.type getInt,@function
|
||||||
|
getInt: # @getInt
|
||||||
|
# %bb.0:
|
||||||
|
addi sp, sp, -16
|
||||||
|
sw ra, 12(sp) # 4-byte Folded Spill
|
||||||
|
lui a0, %hi(.L.str)
|
||||||
|
addi a0, a0, %lo(.L.str)
|
||||||
|
addi a1, sp, 8
|
||||||
|
call scanf
|
||||||
|
lw a0, 8(sp)
|
||||||
|
lw ra, 12(sp) # 4-byte Folded Reload
|
||||||
|
addi sp, sp, 16
|
||||||
|
ret
|
||||||
|
.Lfunc_end10:
|
||||||
|
.size getInt, .Lfunc_end10-getInt
|
||||||
|
# -- End function
|
||||||
|
.option pop
|
||||||
|
.option push
|
||||||
|
.option arch, +a, +c, +m
|
||||||
|
.globl .builtin.AllocateClassBody # -- Begin function .builtin.AllocateClassBody
|
||||||
|
.p2align 1
|
||||||
|
.type .builtin.AllocateClassBody,@function
|
||||||
|
.builtin.AllocateClassBody: # @.builtin.AllocateClassBody
|
||||||
|
# %bb.0:
|
||||||
|
tail malloc
|
||||||
|
.Lfunc_end11:
|
||||||
|
.size .builtin.AllocateClassBody, .Lfunc_end11-.builtin.AllocateClassBody
|
||||||
|
# -- End function
|
||||||
|
.option pop
|
||||||
|
.option push
|
||||||
|
.option arch, +a, +c, +m
|
||||||
|
.globl .builtin.GetArrayLength # -- Begin function .builtin.GetArrayLength
|
||||||
|
.p2align 1
|
||||||
|
.type .builtin.GetArrayLength,@function
|
||||||
|
.builtin.GetArrayLength: # @.builtin.GetArrayLength
|
||||||
|
# %bb.0:
|
||||||
|
lbu a1, -3(a0)
|
||||||
|
lbu a2, -4(a0)
|
||||||
|
lbu a3, -2(a0)
|
||||||
|
lbu a0, -1(a0)
|
||||||
|
slli a1, a1, 8
|
||||||
|
or a1, a1, a2
|
||||||
|
slli a3, a3, 16
|
||||||
|
slli a0, a0, 24
|
||||||
|
or a0, a0, a3
|
||||||
|
or a0, a0, a1
|
||||||
|
ret
|
||||||
|
.Lfunc_end12:
|
||||||
|
.size .builtin.GetArrayLength, .Lfunc_end12-.builtin.GetArrayLength
|
||||||
|
# -- End function
|
||||||
|
.option pop
|
||||||
|
.option push
|
||||||
|
.option arch, +a, +c, +m
|
||||||
|
.globl .builtin.RecursiveAllocateArray # -- Begin function .builtin.RecursiveAllocateArray
|
||||||
|
.p2align 1
|
||||||
|
.type .builtin.RecursiveAllocateArray,@function
|
||||||
|
.builtin.RecursiveAllocateArray: # @.builtin.RecursiveAllocateArray
|
||||||
|
# %bb.0:
|
||||||
|
addi sp, sp, -48
|
||||||
|
sw ra, 44(sp) # 4-byte Folded Spill
|
||||||
|
sw s0, 40(sp) # 4-byte Folded Spill
|
||||||
|
sw s1, 36(sp) # 4-byte Folded Spill
|
||||||
|
sw s2, 32(sp) # 4-byte Folded Spill
|
||||||
|
sw s3, 28(sp) # 4-byte Folded Spill
|
||||||
|
sw s4, 24(sp) # 4-byte Folded Spill
|
||||||
|
sw s5, 20(sp) # 4-byte Folded Spill
|
||||||
|
sw s6, 16(sp) # 4-byte Folded Spill
|
||||||
|
sw s7, 12(sp) # 4-byte Folded Spill
|
||||||
|
lw s0, 0(a2)
|
||||||
|
mv s3, a1
|
||||||
|
mv s2, a0
|
||||||
|
srli s5, s0, 8
|
||||||
|
srli s4, s0, 16
|
||||||
|
li a0, 1
|
||||||
|
srli s6, s0, 24
|
||||||
|
bne s2, a0, .LBB13_2
|
||||||
|
# %bb.1:
|
||||||
|
mul a0, s0, s3
|
||||||
|
addi a0, a0, 4
|
||||||
|
call malloc
|
||||||
|
sb s0, 0(a0)
|
||||||
|
sb s5, 1(a0)
|
||||||
|
sb s4, 2(a0)
|
||||||
|
sb s6, 3(a0)
|
||||||
|
addi a0, a0, 4
|
||||||
|
j .LBB13_6
|
||||||
|
.LBB13_2:
|
||||||
|
mv s7, a2
|
||||||
|
slli a0, s0, 2
|
||||||
|
addi a0, a0, 4
|
||||||
|
call malloc
|
||||||
|
sb s0, 0(a0)
|
||||||
|
sb s5, 1(a0)
|
||||||
|
sb s4, 2(a0)
|
||||||
|
sb s6, 3(a0)
|
||||||
|
addi a0, a0, 4
|
||||||
|
blez s0, .LBB13_6
|
||||||
|
# %bb.3:
|
||||||
|
li s1, 0
|
||||||
|
addi s2, s2, -1
|
||||||
|
addi s5, s7, 4
|
||||||
|
mv s4, a0
|
||||||
|
mv s0, a0
|
||||||
|
.LBB13_4: # =>This Inner Loop Header: Depth=1
|
||||||
|
mv a0, s2
|
||||||
|
mv a1, s3
|
||||||
|
mv a2, s5
|
||||||
|
call .builtin.RecursiveAllocateArray
|
||||||
|
lw a1, 0(s7)
|
||||||
|
sw a0, 0(s0)
|
||||||
|
addi s1, s1, 1
|
||||||
|
addi s0, s0, 4
|
||||||
|
blt s1, a1, .LBB13_4
|
||||||
|
# %bb.5:
|
||||||
|
mv a0, s4
|
||||||
|
.LBB13_6:
|
||||||
|
lw ra, 44(sp) # 4-byte Folded Reload
|
||||||
|
lw s0, 40(sp) # 4-byte Folded Reload
|
||||||
|
lw s1, 36(sp) # 4-byte Folded Reload
|
||||||
|
lw s2, 32(sp) # 4-byte Folded Reload
|
||||||
|
lw s3, 28(sp) # 4-byte Folded Reload
|
||||||
|
lw s4, 24(sp) # 4-byte Folded Reload
|
||||||
|
lw s5, 20(sp) # 4-byte Folded Reload
|
||||||
|
lw s6, 16(sp) # 4-byte Folded Reload
|
||||||
|
lw s7, 12(sp) # 4-byte Folded Reload
|
||||||
|
addi sp, sp, 48
|
||||||
|
ret
|
||||||
|
.Lfunc_end13:
|
||||||
|
.size .builtin.RecursiveAllocateArray, .Lfunc_end13-.builtin.RecursiveAllocateArray
|
||||||
|
# -- End function
|
||||||
|
.option pop
|
||||||
|
.type .L.str,@object # @.str
|
||||||
|
.section .rodata.str1.1,"aMS",@progbits,1
|
||||||
|
.L.str:
|
||||||
|
.asciz "%d"
|
||||||
|
.size .L.str, 3
|
||||||
|
|
||||||
|
.type .L.str.1,@object # @.str.1
|
||||||
|
.L.str.1:
|
||||||
|
.asciz "%s"
|
||||||
|
.size .L.str.1, 3
|
||||||
|
|
||||||
|
.type .L.str.2,@object # @.str.2
|
||||||
|
.L.str.2:
|
||||||
|
.asciz "%s\n"
|
||||||
|
.size .L.str.2, 4
|
||||||
|
|
||||||
|
.type .L.str.3,@object # @.str.3
|
||||||
|
.L.str.3:
|
||||||
|
.asciz "%d\n"
|
||||||
|
.size .L.str.3, 4
|
||||||
|
|
||||||
|
.type .L.str.4,@object # @.str.4
|
||||||
|
.L.str.4:
|
||||||
|
.asciz "%c"
|
||||||
|
.size .L.str.4, 3
|
||||||
|
|
||||||
|
.ident "Ubuntu clang version 18.1.8 (++20240731024944+3b5b5c1ec4a3-1~exp1~20240731145000.144)"
|
||||||
|
.section ".note.GNU-stack","",@progbits
|
@ -1,6 +1,6 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include "astnode_visitor.h"
|
#include "semantic_visitor.h"
|
||||||
#include "scope.hpp"
|
#include "scope.hpp"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
@ -444,6 +444,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(AssignExpr_ASTNode *node) {
|
|||||||
if (node->dest->expr_type_info != node->src->expr_type_info) {
|
if (node->dest->expr_type_info != node->src->expr_type_info) {
|
||||||
throw SemanticError("Type Mismatch", 1);
|
throw SemanticError("Type Mismatch", 1);
|
||||||
}
|
}
|
||||||
|
node->expr_type_info = node->src->expr_type_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ASTSemanticCheckVisitor::ActuralVisit(ThisExpr_ASTNode *node) {
|
void ASTSemanticCheckVisitor::ActuralVisit(ThisExpr_ASTNode *node) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <argparse/argparse.hpp>
|
#include <argparse/argparse.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include "IR/IR.h"
|
||||||
#include "semantic/semantic.h"
|
#include "semantic/semantic.h"
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
@ -24,6 +25,7 @@ int main(int argc, char **argv) {
|
|||||||
std::shared_ptr<Program_ASTNode> ast;
|
std::shared_ptr<Program_ASTNode> ast;
|
||||||
try {
|
try {
|
||||||
SemanticCheck(fin, ast);
|
SemanticCheck(fin, ast);
|
||||||
|
auto IR = BuildIR(ast);
|
||||||
} catch (const SemanticError &err) {
|
} catch (const SemanticError &err) {
|
||||||
std::cout << err.what() << std::endl;
|
std::cout << err.what() << std::endl;
|
||||||
return err.GetErrorCode();
|
return err.GetErrorCode();
|
||||||
|
Reference in New Issue
Block a user