From 2ad566cc7b125a8e7687dd260b71d49eddc9b03e Mon Sep 17 00:00:00 2001 From: Tuowen Zhao Date: Mon, 10 Oct 2016 14:04:14 -0600 Subject: clang frontend split --- CMakeLists.txt | 8 +- include/frontend/clang.h | 8 + include/ir_chill.hh | 493 ++++++++++ include/ir_clang.hh | 515 ---------- include/stencil.hh | 2 +- src/ast/chillASTs.cc | 2108 +++++++++++++++++++++++++++++++++++++++++ src/chillASTs.cc | 2108 ----------------------------------------- src/frontend/clang.cpp | 790 ++++++++++++++++ src/ir_chill.cc | 1432 ++++++++++++++++++++++++++++ src/ir_clang.cc | 2350 ---------------------------------------------- 10 files changed, 4838 insertions(+), 4976 deletions(-) create mode 100644 include/frontend/clang.h create mode 100755 include/ir_chill.hh delete mode 100755 include/ir_clang.hh create mode 100644 src/ast/chillASTs.cc delete mode 100644 src/chillASTs.cc create mode 100644 src/frontend/clang.cpp create mode 100755 src/ir_chill.cc delete mode 100755 src/ir_clang.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 4dade19..53a38d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,13 +25,16 @@ set(CORE_SRC ) set(IR_CHILL_SRC - src/ir_clang.cc + src/ir_chill.cc ) set(AST_CHILL_SRC - src/chillASTs.cc + src/ast/chillASTs.cc src/ast/node.cpp ) +set(CLANG_FRONTEND + src/frontend/clang.cpp) + set(PYTHON_SRC src/chillmodule.cc ) @@ -94,6 +97,7 @@ add_executable(chill src/chill.cc ${CORE_SRC} ${PYTHON_SRC} + ${CLANG_FRONTEND} ${IR_CHILL_SRC} ${AST_CHILL_SRC} ${PRINTER_SRC}) diff --git a/include/frontend/clang.h b/include/frontend/clang.h new file mode 100644 index 0000000..4e11eb1 --- /dev/null +++ b/include/frontend/clang.h @@ -0,0 +1,8 @@ +// +// Created by ztuowen on 10/10/16. +// + +#ifndef CHILL_CLANG_H +#define CHILL_CLANG_H + +#endif //CHILL_CLANG_H diff --git a/include/ir_chill.hh b/include/ir_chill.hh new file mode 100755 index 0000000..bbd7fd5 --- /dev/null +++ b/include/ir_chill.hh @@ -0,0 +1,493 @@ +#ifndef IR_CLANG_HH +#define IR_CLANG_HH + +#include +#include "ir_code.hh" +#include "chill_error.hh" + +#define __STDC_CONSTANT_MACROS + +#include "clang/AST/Decl.h" +#include "clang/AST/Expr.h" +#include "clang/AST/ParentMap.h" + +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/GlobalDecl.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Frontend/ASTConsumers.h" +#include "clang/Frontend/FrontendActions.h" + +#include "clang/CodeGen/CodeGenAction.h" +#include "clang/Driver/Compilation.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/Tool.h" +#include "clang/Frontend/CompilerInvocation.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendDiagnostic.h" +#include "clang/Frontend/TextDiagnosticPrinter.h" +#include "clang/Basic/DiagnosticOptions.h" + +#include "chillAST.h" + +extern std::vector VariableDeclarations; // a global. TODO +extern std::vector FunctionDeclarations; + +struct IR_chillScalarSymbol : public IR_ScalarSymbol { + chillAST_VarDecl *chillvd; + + IR_chillScalarSymbol(const IR_Code *ir, chillAST_VarDecl *vd) { + ir_ = ir; + chillvd = vd; + } + + std::string name() const; + + int size() const; + + bool operator==(const IR_Symbol &that) const; + + IR_Symbol *clone() const; +}; + + +struct IR_chillArraySymbol : public IR_ArraySymbol { + //int indirect_; // TODO Doc + int offset_; // TODO Doc + chillAST_VarDecl *chillvd; + + IR_chillArraySymbol(const IR_Code *ir, chillAST_VarDecl *vd, int offset = 0) { + ir_ = ir; + chillvd = vd; + //indirect_ = indirect; + offset_ = offset; + } + + // No Fortran support! + IR_ARRAY_LAYOUT_TYPE layout_type() const { + return IR_ARRAY_LAYOUT_ROW_MAJOR; + } + + std::string name() const; + + int elem_size() const; + + int n_dim() const; + + omega::CG_outputRepr *size(int dim) const; + + bool operator!=(const IR_Symbol &that) const; + + bool operator==(const IR_Symbol &that) const; + + IR_Symbol *clone() const; + + // TODO Hack to pass build + IR_CONSTANT_TYPE elem_type() const { + fprintf(stderr, "Not implemented elem_type in IR_chillArraySymbol"); + return IR_CONSTANT_UNKNOWN; + }; + +}; + + +struct IR_chillConstantRef : public IR_ConstantRef { + union { + omega::coef_t i_; + double f_; + }; + + IR_chillConstantRef(const IR_Code *ir, omega::coef_t i) { + ir_ = ir; + type_ = IR_CONSTANT_INT; + i_ = i; + } + + IR_chillConstantRef(const IR_Code *ir, double f) { + ir_ = ir; + type_ = IR_CONSTANT_FLOAT; + f_ = f; + } + + omega::coef_t integer() const { + assert(is_integer()); + return i_; + } + + bool operator==(const IR_Ref &that) const; + + omega::CG_outputRepr *convert(); + + IR_Ref *clone() const; + +}; + +enum OP_POSITION { + OP_DEST = -1, OP_UNKNOWN, OP_SRC +}; +#define OP_LEFT OP_DEST +#define OP_RIGHT OP_SRC + +struct IR_chillScalarRef : public IR_ScalarRef { + /*! + * @brief the position of the operand + * -1 means destination operand, 0== unknown, 1 == source operand + */ + OP_POSITION op_pos_; + //chillAST_BinaryOperator *bop; // binary op that contains this scalar? + chillAST_DeclRefExpr *dre; //!< declrefexpr that uses this scalar ref, if that exists + chillAST_VarDecl *chillvd; //!< the vardecl for this scalar + + IR_chillScalarRef(const IR_Code *ir, chillAST_BinaryOperator *ins, OP_POSITION pos) { + CHILL_ERROR("Not implemented"); + exit(-1); + // this constructor takes a binary operation and an indicator of which side of the op to use, + // and finds the scalar in the lhs or rhs of the binary op. + ir_ = ir; + dre = NULL; + if (pos == OP_LEFT) { + chillAST_Node *lhs = ins->getLHS(); + if (lhs->isDeclRefExpr()) { + chillAST_DeclRefExpr *DRE = (chillAST_DeclRefExpr *) lhs; + dre = DRE; + chillvd = DRE->getVarDecl(); + } else if (lhs->isVarDecl()) { + chillvd = (chillAST_VarDecl *) lhs; + } else { + CHILL_ERROR("IR_chillScalarRef constructor, I'm confused\n"); + exit(-1); + } + } else { + chillAST_Node *rhs = ins->getRHS(); + if (rhs->isDeclRefExpr()) { + chillAST_DeclRefExpr *DRE = (chillAST_DeclRefExpr *) rhs; + dre = DRE; + chillvd = DRE->getVarDecl(); + } else if (rhs->isVarDecl()) { + chillvd = (chillAST_VarDecl *) rhs; + } else { + CHILL_ERROR("IR_chillScalarRef constructor, I'm confused\n"); + exit(-1); + } + } + op_pos_ = pos; + } + + IR_chillScalarRef(const IR_Code *ir, chillAST_DeclRefExpr *d) { + ir_ = ir; + dre = d; + chillvd = d->getVarDecl(); + op_pos_ = OP_UNKNOWN; + } + + IR_chillScalarRef(const IR_Code *ir, chillAST_VarDecl *vardecl) { + ir_ = ir; + dre = NULL; + chillvd = vardecl; + op_pos_ = OP_UNKNOWN; + } + + + bool is_write() const; + + IR_ScalarSymbol *symbol() const; + + bool operator==(const IR_Ref &that) const; + + omega::CG_outputRepr *convert(); + + IR_Ref *clone() const; +}; + + +struct IR_chillArrayRef : public IR_ArrayRef { + chillAST_ArraySubscriptExpr *chillASE; + int iswrite; + + IR_chillArrayRef(const IR_Code *ir, chillAST_ArraySubscriptExpr *ase, int write) { + ir_ = ir; + chillASE = ase; + iswrite = write; + } + + bool is_write() const; + + omega::CG_outputRepr *index(int dim) const; + + IR_ArraySymbol *symbol() const; + + bool operator!=(const IR_Ref &that) const; + + bool operator==(const IR_Ref &that) const; + + omega::CG_outputRepr *convert(); + + IR_Ref *clone() const; + + // Not implemented + // virtual void Dump() const; +}; + + +struct IR_chillLoop : public IR_Loop { + int step_size_; + + chillAST_DeclRefExpr *chillindex; // the loop index variable (I) // was DeclRefExpr + chillAST_ForStmt *chillforstmt; + chillAST_Node *chilllowerbound; + chillAST_Node *chillupperbound; + chillAST_Node *chillbody; // presumably a compound statement, but not guaranteeed + IR_CONDITION_TYPE conditionoperator; + + IR_chillLoop(const IR_Code *ir, clang::ForStmt *tf); + + IR_chillLoop(const IR_Code *ir, chillAST_ForStmt *forstmt); + + ~IR_chillLoop() {} + + IR_ScalarSymbol *index() const { return new IR_chillScalarSymbol(ir_, chillindex->getVarDecl()); } + + omega::CG_outputRepr *lower_bound() const; + + omega::CG_outputRepr *upper_bound() const; + + IR_CONDITION_TYPE stop_cond() const; + + IR_Block *body() const; + + // Handle following types of increment expressions: + + // Unary increment/decrement + // i += K OR i -= K + // i = i + K OR i = i - K + // where K is positive + int step_size() const { return step_size_; } // K is always an integer ??? + IR_Control *clone() const; + + IR_Block *convert(); + + virtual void dump() const; +}; + + +struct IR_chillBlock : public IR_Block { // ONLY ONE OF bDecl or cs_ will be nonNULL ?? +private: + //StmtList bDecl_; // declarations in the block?? + //clang::CompoundStmt *cs_; // will a block always have a compound statement? (no) + //StmtList *stmts; // ?? +public: + + // Block is a basic block?? (no, just a chunk of code ) + std::vector statements; + + IR_chillBlock(const IR_chillBlock *CB) { // clone existing IR_chillBlock + ir_ = CB->ir_; + for (int i = 0; i < CB->statements.size(); i++) statements.push_back(CB->statements[i]); + } + + IR_chillBlock(const IR_Code *ir, std::vector ast) : statements(ast) { + ir_ = ir; + } + + IR_chillBlock(const IR_Code *ir, chillAST_Node *ast = NULL) { // : cs_(NULL), bDecl_(NULL) { + ir_ = ir; + if (ast != NULL) + statements.push_back(ast); + } + + + ~IR_chillBlock() {} + + omega::CG_outputRepr *extract() const; + + omega::CG_outputRepr *original() const; + + IR_Control *clone() const; + + //StmtList getStmtList() const; + std::vector getStmtList() const; + + int numstatements() { return statements.size(); }; + + void addStatement(chillAST_Node *s); + + void dump() const; +}; + +struct IR_chillIf: public IR_If { + chillAST_Node *code; + + IR_chillIf(const IR_Code *ir, chillAST_Node *ti) { + ir_ = ir; + code = ti; + } + ~IR_chillIf() { + } + omega::CG_outputRepr *condition() const; + IR_Block *then_body() const; + IR_Block *else_body() const; + IR_Block *convert(); + IR_Control *clone() const; +}; + +class aClangCompiler { +private: + //Chill_ASTConsumer *astConsumer_; + clang::ASTContext *astContext_; + + clang::DiagnosticOptions *diagnosticOptions; + clang::TextDiagnosticPrinter *pTextDiagnosticPrinter; + llvm::IntrusiveRefCntPtr diagID; + clang::DiagnosticsEngine *diagnosticsEngine; + clang::CompilerInstance *Clang; + clang::Preprocessor *preprocessor; + //FileManager *FileMgr; + //clang::CompilerInvocation *CI; + + clang::FileManager *fileManager; + clang::SourceManager *sourceManager; + + // UNUSED? + clang::Diagnostic *diagnostic; + clang::LangOptions *languageOptions; + clang::HeaderSearchOptions *headerSearchOptions; + //clang::HeaderSearch *headerSearch; + std::shared_ptr targetOptions; + clang::TargetInfo *pTargetInfo; + clang::PreprocessorOptions *preprocessorOptions; + clang::FrontendOptions *frontendOptions; + clang::IdentifierTable *idTable; + clang::SelectorTable *selTable; + clang::Builtin::Context *builtinContext; + + +public: + char *SourceFileName; + chillAST_SourceFile *entire_file_AST; // TODO move out of public + + aClangCompiler(char *filename); // constructor + chillAST_FunctionDecl *findprocedurebyname(char *name); // someday, return the chill AST + clang::FunctionDecl *FD; + + //Chill_ASTConsumer *getASTConsumer() { return astConsumer_; } + clang::ASTContext *getASTContext() { return astContext_; } + + clang::SourceManager *getASTSourceManager() { return sourceManager; }; +}; + + +// singleton class for global clang initialization +// TODO: Add support for multiple files in same script +class IR_clangCode_Global_Init { +private: + static IR_clangCode_Global_Init *pinstance; // the one and only + // protecting the constructor is the SINGLETON PATTERN. a global by any other name + // IR_clangCode_Global_Init(); + ~IR_clangCode_Global_Init(); // is this hidden, too? + chillAST_FunctionDecl *chillFD; // the original C code + + clang::ASTContext *astContext_; + clang::SourceManager *sourceManager; +public: + clang::ASTContext *getASTContext() { return astContext_; } + + clang::SourceManager *getSourceManager() { return sourceManager; }; + + static IR_clangCode_Global_Init *Instance(char **argv); + + static IR_clangCode_Global_Init *Instance() { return pinstance; }; + aClangCompiler *ClangCompiler; // this is the thing we really just want one of + + + void setCurrentFunction(chillAST_Node *F) { chillFD = (chillAST_FunctionDecl *) F; }; + + chillAST_FunctionDecl *getCurrentFunction() { return chillFD; }; + + + void setCurrentASTContext(clang::ASTContext *A) { astContext_ = A; }; + + clang::ASTContext *getCurrentASTContext() { return astContext_; }; + + void setCurrentASTSourceManager(clang::SourceManager *S) { sourceManager = S; }; + + clang::SourceManager *getCurrentASTSourceManager() { return sourceManager; }; +}; + + +class IR_clangCode : public IR_Code { // for an entire file? A single function? +protected: + + // + char *filename; + char *procedurename; + char *outfilename; + + + chillAST_Node *entire_file_AST; + chillAST_FunctionDecl *chillfunc; // the function we're currenly modifying + + std::vector entire_file_symbol_table; + // loop symbol table?? for (int i=0; ... ) ?? + + + + clang::FunctionDecl *func_; // a clang construct the function we're currenly modifying + clang::ASTContext *astContext_; + clang::SourceManager *sourceManager; + + // firstScope; + // symboltable1,2,3 ?? + // topleveldecls + // + +public: + clang::ASTContext *getASTContext() { return astContext_; }; + + clang::SourceManager *getASTSourceManager() { return sourceManager; }; + + IR_clangCode(const char *filename, const char *proc_name); + IR_clangCode(const char *filename, const char *proc_name, const char *dest_name); + + ~IR_clangCode(); + + IR_ScalarSymbol *CreateScalarSymbol(const IR_Symbol *sym, int i); + + IR_ArraySymbol *CreateArraySymbol(const IR_Symbol *sym, std::vector &size, int i); + + IR_ScalarRef *CreateScalarRef(const IR_ScalarSymbol *sym); + + IR_ArrayRef *CreateArrayRef(const IR_ArraySymbol *sym, std::vector &index); + + virtual bool FromSameStmt(IR_ArrayRef *A, IR_ArrayRef *B); + + int ArrayIndexStartAt() { return 0; } // TODO FORTRAN + + std::vector FindScalarRef(const omega::CG_outputRepr *repr) const; + + std::vector FindArrayRef(const omega::CG_outputRepr *repr) const; + + std::vector FindOneLevelControlStructure(const IR_Block *block) const; + + IR_Block *MergeNeighboringControlStructures(const std::vector &controls) const; + + IR_Block *GetCode() const; + + void ReplaceCode(IR_Control *old, omega::CG_outputRepr *repr); + + void ReplaceExpression(IR_Ref *old, omega::CG_outputRepr *repr); + + IR_CONDITION_TYPE QueryBooleanExpOperation(const omega::CG_outputRepr *) const; + + IR_OPERATION_TYPE QueryExpOperation(const omega::CG_outputRepr *repr) const; + + std::vector QueryExpOperand(const omega::CG_outputRepr *repr) const; + + IR_Ref *Repr2Ref(const omega::CG_outputRepr *) const; + + friend class IR_chillArraySymbol; + + friend class IR_chillArrayRef; +}; + +#endif diff --git a/include/ir_clang.hh b/include/ir_clang.hh deleted file mode 100755 index 94fbc95..0000000 --- a/include/ir_clang.hh +++ /dev/null @@ -1,515 +0,0 @@ -#ifndef IR_CLANG_HH -#define IR_CLANG_HH - -#include -#include "ir_code.hh" -#include "chill_error.hh" - -#define __STDC_CONSTANT_MACROS - -#include "clang/AST/Decl.h" -#include "clang/AST/Expr.h" -#include "clang/AST/ParentMap.h" - -#include "clang/AST/ASTConsumer.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/GlobalDecl.h" -#include "clang/AST/RecursiveASTVisitor.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Frontend/ASTConsumers.h" -#include "clang/Frontend/FrontendActions.h" - -#include "clang/CodeGen/CodeGenAction.h" -#include "clang/Driver/Compilation.h" -#include "clang/Driver/Driver.h" -#include "clang/Driver/Tool.h" -#include "clang/Frontend/CompilerInvocation.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/FrontendDiagnostic.h" -#include "clang/Frontend/TextDiagnosticPrinter.h" -#include "clang/Basic/DiagnosticOptions.h" - -#include "chillAST.h" - -extern std::vector VariableDeclarations; // a global. TODO - -typedef llvm::SmallVector StmtList; // TODO delete - -struct IR_chillScalarSymbol : public IR_ScalarSymbol { - chillAST_VarDecl *chillvd; - - IR_chillScalarSymbol(const IR_Code *ir, chillAST_VarDecl *vd) { - ir_ = ir; - chillvd = vd; - } - - std::string name() const; - - int size() const; - - bool operator==(const IR_Symbol &that) const; - - IR_Symbol *clone() const; -}; - - -struct IR_chillArraySymbol : public IR_ArraySymbol { - //int indirect_; // what was this? - int offset_; // what is this? - chillAST_VarDecl *chillvd; - - IR_chillArraySymbol(const IR_Code *ir, chillAST_VarDecl *vd, int offset = 0) { - //if ( vd == 0 ) - //fprintf(stderr, "IR_chillArraySymbol::IR_chillArraySymbol (%s) vd 0x%x\n", vd->varname, vd); - ir_ = ir; - chillvd = vd; - //indirect_ = indirect; - offset_ = offset; - } - - - // No Fortran support! - IR_ARRAY_LAYOUT_TYPE layout_type() const { - return IR_ARRAY_LAYOUT_ROW_MAJOR; - } - - std::string name() const; - - int elem_size() const; - - int n_dim() const; - - omega::CG_outputRepr *size(int dim) const; - - bool operator!=(const IR_Symbol &that) const; - - bool operator==(const IR_Symbol &that) const; - - IR_Symbol *clone() const; - - // TODO Hack to pass build - IR_CONSTANT_TYPE elem_type() const { - fprintf(stderr, "Not implemented elem_type in IR_chillArraySymbol"); - return IR_CONSTANT_UNKNOWN; - }; - -}; - - -struct IR_chillConstantRef : public IR_ConstantRef { - union { - omega::coef_t i_; - double f_; - }; - - IR_chillConstantRef(const IR_Code *ir, omega::coef_t i) { - ir_ = ir; - type_ = IR_CONSTANT_INT; - i_ = i; - } - - IR_chillConstantRef(const IR_Code *ir, double f) { - ir_ = ir; - type_ = IR_CONSTANT_FLOAT; - f_ = f; - } - - omega::coef_t integer() const { - assert(is_integer()); - return i_; - } - - bool operator==(const IR_Ref &that) const; - - omega::CG_outputRepr *convert(); - - IR_Ref *clone() const; - -}; - -enum OP_POSITION { - OP_DEST = -1, OP_UNKNOWN, OP_SRC -}; -#define OP_LEFT OP_DEST -#define OP_RIGHT OP_SRC - -struct IR_chillScalarRef : public IR_ScalarRef { - OP_POSITION op_pos_; // -1 means destination operand, 0== unknown, 1 == source operand - //chillAST_BinaryOperator *bop; // binary op that contains this scalar? - chillAST_DeclRefExpr *dre; // declrefexpr that uses this scalar ref, if that exists - chillAST_VarDecl *chillvd; // the vardecl for this scalar - - IR_chillScalarRef(const IR_Code *ir, chillAST_BinaryOperator *ins, OP_POSITION pos) { - fprintf(stderr, "\n***** new IR_xxxxScalarRef( ir, ins, pos ) *****\n\n"); - exit(-1); - // this constructor takes a binary operation and an indicator of which side of the op to use, - // and finds the scalar in the lhs or rhs of the binary op. - ir_ = ir; - dre = NULL; - //bop = ins; // do we need this? - if (pos == OP_LEFT) { - chillAST_Node *lhs = ins->getLHS(); - if (lhs->isDeclRefExpr()) { - chillAST_DeclRefExpr *DRE = (chillAST_DeclRefExpr *) lhs; - dre = DRE; - chillvd = DRE->getVarDecl(); - } else if (lhs->isVarDecl()) { - chillvd = (chillAST_VarDecl *) lhs; - } else { - fprintf(stderr, "IR_chillScalarRef constructor, I'm confused\n"); - exit(-1); - } - } else { - chillAST_Node *rhs = ins->getRHS(); - if (rhs->isDeclRefExpr()) { - chillAST_DeclRefExpr *DRE = (chillAST_DeclRefExpr *) rhs; - dre = DRE; - chillvd = DRE->getVarDecl(); - } else if (rhs->isVarDecl()) { - chillvd = (chillAST_VarDecl *) rhs; - } else { - fprintf(stderr, "IR_chillScalarRef constructor, I'm confused\n"); - exit(-1); - } - } - op_pos_ = pos; - } - - IR_chillScalarRef(const IR_Code *ir, chillAST_DeclRefExpr *d) { - // fprintf(stderr, "\n***** new IR_xxxxScalarRef( ir, REF EXPR sym %s ) *****\n\n", d->getVarDecl()->varname); - //fprintf(stderr, "new IR_chillScalarRef with a DECLREFEXPR (has dre) \n"); - ir_ = ir; - dre = d; - //bop = NULL; - chillvd = d->getVarDecl(); - op_pos_ = OP_UNKNOWN; - - //fprintf(stderr, "\nScalarRef has:\n"); - //fprintf(stderr, "assignment op DOESNT EXIST\n"); - //fprintf(stderr, "ins_pos %d\n", ins_pos_); - //fprintf(stderr, "op_pos %d\n", op_pos_); - //fprintf(stderr, "ref expr dre = 0x%x\n", dre); - } - - IR_chillScalarRef(const IR_Code *ir, chillAST_VarDecl *vardecl) { - fprintf(stderr, - "\n***** new IR_xxxxScalarRef( ir, sym 0x1234567 ) ***** THIS SHOULD NEVER HAPPEN\n\n"); - fprintf(stderr, "vardecl %s\n", vardecl->varname); - ir_ = ir; - dre = NULL; - fprintf(stderr, "new IR_chillScalarRef with a vardecl but no dre\n"); - //bop = NULL; - chillvd = vardecl; - op_pos_ = OP_UNKNOWN; - - //fprintf(stderr, "\nScalarRef has:\n"); - //fprintf(stderr, "assignment op DOESNT EXIST\n"); - //fprintf(stderr, "ins_pos %d\n", ins_pos_); - //fprintf(stderr, "op_pos %d\n", op_pos_); - //fprintf(stderr, "ref expr dre = 0x%x\n", dre); - } - - - bool is_write() const; - - IR_ScalarSymbol *symbol() const; - - bool operator==(const IR_Ref &that) const; - - omega::CG_outputRepr *convert(); - - IR_Ref *clone() const; -}; - - -struct IR_chillArrayRef : public IR_ArrayRef { - chillAST_ArraySubscriptExpr *chillASE; - int iswrite; - - IR_chillArrayRef(const IR_Code *ir, chillAST_ArraySubscriptExpr *ase, int write) { - ir_ = ir; - chillASE = ase; - iswrite = write; - } - - bool is_write() const; - - omega::CG_outputRepr *index(int dim) const; - - IR_ArraySymbol *symbol() const; - - bool operator!=(const IR_Ref &that) const; - - bool operator==(const IR_Ref &that) const; - - omega::CG_outputRepr *convert(); - - IR_Ref *clone() const; - - // Not implemented - // virtual void Dump() const; -}; - - -struct IR_chillLoop : public IR_Loop { - int step_size_; - - chillAST_DeclRefExpr *chillindex; // the loop index variable (I) // was DeclRefExpr - chillAST_ForStmt *chillforstmt; - chillAST_Node *chilllowerbound; - chillAST_Node *chillupperbound; - chillAST_Node *chillbody; // presumably a compound statement, but not guaranteeed - IR_CONDITION_TYPE conditionoperator; - - IR_chillLoop(const IR_Code *ir, clang::ForStmt *tf); - - IR_chillLoop(const IR_Code *ir, chillAST_ForStmt *forstmt); - - ~IR_chillLoop() {} - - IR_ScalarSymbol *index() const { return new IR_chillScalarSymbol(ir_, chillindex->getVarDecl()); } - - omega::CG_outputRepr *lower_bound() const; - - omega::CG_outputRepr *upper_bound() const; - - IR_CONDITION_TYPE stop_cond() const; - - IR_Block *body() const; - - // Handle following types of increment expressions: - - // Unary increment/decrement - // i += K OR i -= K - // i = i + K OR i = i - K - // where K is positive - int step_size() const { return step_size_; } // K is always an integer ??? - IR_Control *clone() const; - - IR_Block *convert(); - - virtual void dump() const; -}; - - -struct IR_chillBlock : public IR_Block { // ONLY ONE OF bDecl or cs_ will be nonNULL ?? -private: - //StmtList bDecl_; // declarations in the block?? - //clang::CompoundStmt *cs_; // will a block always have a compound statement? (no) - //StmtList *stmts; // ?? -public: - - // Block is a basic block?? (no, just a chunk of code ) - std::vector statements; - - IR_chillBlock(const IR_chillBlock *CB) { // clone existing IR_chillBlock - ir_ = CB->ir_; - for (int i = 0; i < CB->statements.size(); i++) statements.push_back(CB->statements[i]); - } - - IR_chillBlock(const IR_Code *ir, std::vector ast) : statements(ast) { - ir_ = ir; - } - - IR_chillBlock(const IR_Code *ir, chillAST_Node *ast = NULL) { // : cs_(NULL), bDecl_(NULL) { - ir_ = ir; - if (ast != NULL) - statements.push_back(ast); - } - - - ~IR_chillBlock() {} - - omega::CG_outputRepr *extract() const; - - omega::CG_outputRepr *original() const; - - IR_Control *clone() const; - - //StmtList getStmtList() const; - std::vector getStmtList() const; - - int numstatements() { return statements.size(); }; - - void addStatement(chillAST_Node *s); - - void dump() const; -}; - -struct IR_chillIf: public IR_If { - chillAST_Node *code; - - IR_chillIf(const IR_Code *ir, chillAST_Node *ti) { - ir_ = ir; - code = ti; - } - ~IR_chillIf() { - } - omega::CG_outputRepr *condition() const; - IR_Block *then_body() const; - IR_Block *else_body() const; - IR_Block *convert(); - IR_Control *clone() const; -}; - -class aClangCompiler { -private: - //Chill_ASTConsumer *astConsumer_; - clang::ASTContext *astContext_; - - clang::DiagnosticOptions *diagnosticOptions; - clang::TextDiagnosticPrinter *pTextDiagnosticPrinter; - llvm::IntrusiveRefCntPtr diagID; - clang::DiagnosticsEngine *diagnosticsEngine; - clang::CompilerInstance *Clang; - clang::Preprocessor *preprocessor; - //FileManager *FileMgr; - //clang::CompilerInvocation *CI; - - clang::FileManager *fileManager; - clang::SourceManager *sourceManager; - - // UNUSED? - clang::Diagnostic *diagnostic; - clang::LangOptions *languageOptions; - clang::HeaderSearchOptions *headerSearchOptions; - //clang::HeaderSearch *headerSearch; - std::shared_ptr targetOptions; - clang::TargetInfo *pTargetInfo; - clang::PreprocessorOptions *preprocessorOptions; - clang::FrontendOptions *frontendOptions; - clang::IdentifierTable *idTable; - clang::SelectorTable *selTable; - clang::Builtin::Context *builtinContext; - - -public: - char *SourceFileName; - chillAST_SourceFile *entire_file_AST; // TODO move out of public - - aClangCompiler(char *filename); // constructor - chillAST_FunctionDecl *findprocedurebyname(char *name); // someday, return the chill AST - clang::FunctionDecl *FD; - - //Chill_ASTConsumer *getASTConsumer() { return astConsumer_; } - clang::ASTContext *getASTContext() { return astContext_; } - - clang::SourceManager *getASTSourceManager() { return sourceManager; }; -}; - - -// singleton class for global clang initialization -// TODO: Add support for multiple files in same script -class IR_clangCode_Global_Init { -private: - static IR_clangCode_Global_Init *pinstance; // the one and only - // protecting the constructor is the SINGLETON PATTERN. a global by any other name - // IR_clangCode_Global_Init(); - ~IR_clangCode_Global_Init(); // is this hidden, too? - chillAST_FunctionDecl *chillFD; // the original C code - - clang::ASTContext *astContext_; - clang::SourceManager *sourceManager; -public: - clang::ASTContext *getASTContext() { return astContext_; } - - clang::SourceManager *getSourceManager() { return sourceManager; }; - - static IR_clangCode_Global_Init *Instance(char **argv); - - static IR_clangCode_Global_Init *Instance() { return pinstance; }; - aClangCompiler *ClangCompiler; // this is the thing we really just want one of - - - void setCurrentFunction(chillAST_Node *F) { chillFD = (chillAST_FunctionDecl *) F; }; - - chillAST_FunctionDecl *getCurrentFunction() { return chillFD; }; - - - void setCurrentASTContext(clang::ASTContext *A) { astContext_ = A; }; - - clang::ASTContext *getCurrentASTContext() { return astContext_; }; - - void setCurrentASTSourceManager(clang::SourceManager *S) { sourceManager = S; }; - - clang::SourceManager *getCurrentASTSourceManager() { return sourceManager; }; -}; - - -class IR_clangCode : public IR_Code { // for an entire file? A single function? -protected: - - // - char *filename; - char *procedurename; - char *outfilename; - - - chillAST_Node *entire_file_AST; - chillAST_FunctionDecl *chillfunc; // the function we're currenly modifying - - std::vector entire_file_symbol_table; - // loop symbol table?? for (int i=0; ... ) ?? - - - - clang::FunctionDecl *func_; // a clang construct the function we're currenly modifying - clang::ASTContext *astContext_; - clang::SourceManager *sourceManager; - - // firstScope; - // symboltable1,2,3 ?? - // topleveldecls - // - -public: - clang::ASTContext *getASTContext() { return astContext_; }; - - clang::SourceManager *getASTSourceManager() { return sourceManager; }; - - IR_clangCode(const char *filename, const char *proc_name); - IR_clangCode(const char *filename, const char *proc_name, const char *dest_name); - - ~IR_clangCode(); - - IR_ScalarSymbol *CreateScalarSymbol(const IR_Symbol *sym, int i); - - IR_ArraySymbol *CreateArraySymbol(const IR_Symbol *sym, std::vector &size, int i); - - IR_ScalarRef *CreateScalarRef(const IR_ScalarSymbol *sym); - - IR_ArrayRef *CreateArrayRef(const IR_ArraySymbol *sym, std::vector &index); - - virtual bool FromSameStmt(IR_ArrayRef *A, IR_ArrayRef *B); - - int ArrayIndexStartAt() { return 0; } // TODO FORTRAN - - std::vector FindScalarRef(const omega::CG_outputRepr *repr) const; - - std::vector FindArrayRef(const omega::CG_outputRepr *repr) const; - - std::vector FindOneLevelControlStructure(const IR_Block *block) const; - - IR_Block *MergeNeighboringControlStructures(const std::vector &controls) const; - - IR_Block *GetCode() const; - - void ReplaceCode(IR_Control *old, omega::CG_outputRepr *repr); - - void ReplaceExpression(IR_Ref *old, omega::CG_outputRepr *repr); - - IR_CONDITION_TYPE QueryBooleanExpOperation(const omega::CG_outputRepr *) const; - - IR_OPERATION_TYPE QueryExpOperation(const omega::CG_outputRepr *repr) const; - - std::vector QueryExpOperand(const omega::CG_outputRepr *repr) const; - - IR_Ref *Repr2Ref(const omega::CG_outputRepr *) const; - - friend class IR_chillArraySymbol; - - friend class IR_chillArrayRef; -}; - - -#endif diff --git a/include/stencil.hh b/include/stencil.hh index 09471e8..e3b18ea 100644 --- a/include/stencil.hh +++ b/include/stencil.hh @@ -1,7 +1,7 @@ #pragma once -#include "ir_clang.hh" +#include "ir_chill.hh" #include "chillAST/chillASTs.hh" //#include diff --git a/src/ast/chillASTs.cc b/src/ast/chillASTs.cc new file mode 100644 index 0000000..1e670a7 --- /dev/null +++ b/src/ast/chillASTs.cc @@ -0,0 +1,2108 @@ +#include +#include +#include +#include "chillAST.h" +#include "printer/dump.h" +#include "printer/cfamily.h" + +using namespace std; + +bool streq(const char *a, const char *b) { + return !strcmp(a, b); +} + +char *parseUnderlyingType(const char *sometype) { + int len = strlen(sometype); + CHILL_DEBUG_PRINT("parseUnderlyingType( %s )\n", sometype); + char *underlying = strdup(sometype); + char *p; + + p = &underlying[len - 1]; + + while (p > underlying) + if (*p == ' ' || *p == '*') + --p; + else if (*p == ']') { + while (*p != '[') --p; + --p; + } + else break; + + *(p + 1) = '\0'; + + return underlying; +} + +char *splitVariableName(char *name) { + char *cdot = strstr(name, "."); + char *carrow = strstr(name, "->"); // initial 'c' for const - can't change those + + int pos = INT16_MAX, pend; + + if (cdot) pend = pos = (int) (cdot - name); + if (carrow) { + pos = min(pos, (int) (carrow - name)); + pend = pos + 1; + } + + if (pos == INT16_MAX) + return NULL; + + name[pos] = '\0'; + return &name[pend + 1]; + +} + +chillAST_VarDecl *symbolTableFindName(chillAST_SymbolTable *table, const char *name) { + if (!table) return NULL; + int numvars = table->size(); + for (int i = 0; i < numvars; i++) { + chillAST_VarDecl *vd = (*table)[i]; + if (vd->nameis(name)) return vd; + } + return NULL; +} + +chillAST_TypedefDecl *typedefTableFindName(chillAST_TypedefTable *table, const char *name) { + if (!table) return NULL; + int numvars = table->size(); + for (int i = 0; i < numvars; i++) { + chillAST_TypedefDecl *td = (*table)[i]; + if (td->nameis(name)) return td; + } + return NULL; +} + +chillAST_VarDecl *variableDeclFindSubpart(chillAST_VarDecl *decl, const char *name) { + char *varname = strdup(name), *subpart; + + subpart = splitVariableName(varname); + + if (decl->isAStruct()) { + CHILL_DEBUG_PRINT("Finding %s in a struct of type %s\n", varname, decl->getTypeString()); + if (decl->isVarDecl()) { + chillAST_RecordDecl *rd = decl->getStructDef(); + if (rd) { + chillAST_VarDecl *sp = rd->findSubpart(varname); + if (sp) CHILL_DEBUG_PRINT("found a struct member named %s\n", varname); + else + CHILL_DEBUG_PRINT("DIDN'T FIND a struct member named %s\n", varname); + if (!subpart) + return sp; + return variableDeclFindSubpart(sp, subpart); // return the subpart?? + } else { + CHILL_ERROR("no recordDecl\n"); + exit(-1); + } + } else { + CHILL_ERROR("NOT a VarDecl???\n"); // impossible + } + } else { + CHILL_DEBUG_PRINT("false alarm. %s is a variable, but doesn't have subparts\n", varname); + return NULL; + } +} + +chillAST_VarDecl *symbolTableFindVariableNamed(chillAST_SymbolTable *table, const char *name) { + if (!table) return NULL; + + char *varname = strdup(name), *subpart; + + subpart = splitVariableName(varname); + + chillAST_VarDecl *vd = symbolTableFindName(table, varname); + + if (!subpart) + return vd; + return variableDeclFindSubpart(vd, subpart); +} + +char *ulhack(char *brackets) { + CHILL_DEBUG_PRINT("ulhack( \"%s\" -> \n", brackets); + int len = strlen(brackets); + for (int i = 0; i < len - 2; i++) { + if (isdigit(brackets[i])) { + if (brackets[i + 1] == 'U' && brackets[i + 2] == 'L') { // remove + for (int j = i + 3; j < len; j++) brackets[j - 2] = brackets[j]; + len -= 2; + brackets[len] = '\0'; + } + } + } + return brackets; +} + +char *restricthack(char *typeinfo) { + CHILL_DEBUG_PRINT("restricthack( \"%s\" -> \n", typeinfo); + std::string r("__restrict__"); + std::string t(typeinfo); + size_t index = t.find(r); + + if (index == std::string::npos) return typeinfo; + + char *c = &(typeinfo[index]); + char *after = c + 12; + if (*after == ' ') after++; + + while (*after != '\0') *c++ = *after++; + *c = '\0'; + + return typeinfo; + +} + +// TODO DOC +char *parseArrayParts(char *sometype) { + int len = strlen(sometype); + char *arraypart = (char *) calloc(1 + strlen(sometype), sizeof(char));// leak + + int c = 0; + for (int i = 0; i < strlen(sometype);) { + if (sometype[i] == '*') arraypart[c++] = '*'; + if (sometype[i] == '[') { + while (sometype[i] != ']') { + arraypart[c++] = sometype[i++]; + } + arraypart[c++] = ']'; + } + i += 1; + } + ulhack(arraypart); + restricthack(arraypart); + + CHILL_DEBUG_PRINT("parseArrayParts( %s ) => %s\n", sometype, arraypart); + return arraypart; +} + + +//! return the bracketed part of a type, int *buh[32] to int +char *splitTypeInfo(char *underlyingtype) { + char *ap = ulhack(parseArrayParts(underlyingtype)); + + strcpy(underlyingtype, parseUnderlyingType(underlyingtype)); + return ap; // leak unless caller frees this +} + + +bool isRestrict(const char *sometype) { // does not modify sometype + string r("__restrict__"); + string t(sometype); + return (std::string::npos != t.find(r)); +} + +void chillindent(int howfar, FILE *fp) { for (int i = 0; i < howfar; i++) fprintf(fp, " "); } + +chillAST_SourceFile::chillAST_SourceFile(const char *filename) { + if (filename) SourceFileName = strdup(filename); + else SourceFileName = strdup("No Source File"); + symbolTable = new chillAST_SymbolTable(); + typedefTable = new chillAST_TypedefTable(); + FileToWrite = NULL; + frontend = strdup("unknown"); +}; + +void chillAST_SourceFile::printToFile(char *filename) { + char fn[1024]; + + if (NULL == filename) { // build up a filename using original name and frontend if known + if (FileToWrite) { + strcpy(fn, FileToWrite); + } else { + // input name with name of frontend compiler prepended + if (frontend) sprintf(fn, "%s_%s\0", frontend, SourceFileName); + else sprintf(fn, "UNKNOWNFRONTEND_%s\0", SourceFileName); // should never happen + } + } else strcpy(fn, filename); + + std::ofstream fo(fn); + if (fo.fail()) { + CHILL_ERROR("can't open file '%s' for writing\n", fn); + exit(-1); + } + chill::printer::CFamily cp; + cp.print("",this,fo); + +} + +chillAST_MacroDefinition *chillAST_SourceFile::findMacro(const char *name) { + int numMacros = macrodefinitions.size(); + for (int i = 0; i < numMacros; i++) { + if (!strcmp(macrodefinitions[i]->macroName, name)) return macrodefinitions[i]; + } + return NULL; // not found +} + + +chillAST_FunctionDecl *chillAST_SourceFile::findFunction(const char *name) { + int numFuncs = functions.size(); + for (int i = 0; i < numFuncs; i++) { + if (!strcmp(functions[i]->functionName, name)) return functions[i]; + } + return NULL; +} + + +chillAST_Node *chillAST_SourceFile::findCall(const char *name) { + chillAST_MacroDefinition *macro = findMacro(name); + if (macro) return (chillAST_Node *) macro; + chillAST_FunctionDecl *func = findFunction(name); + return func; +} + +chillAST_TypedefDecl::chillAST_TypedefDecl() { + underlyingtype = newtype = arraypart = NULL; + parent = NULL; + metacomment = NULL; + isStruct = isUnion = false; + structname = NULL; + rd = NULL; + isFromSourceFile = true; // default + filename = NULL; +}; + + +chillAST_TypedefDecl::chillAST_TypedefDecl(char *t, const char *nt) { + underlyingtype = strdup(t); + newtype = strdup(nt); + arraypart = NULL; + metacomment = NULL; + isStruct = isUnion = false; + structname = NULL; + rd = NULL; + isFromSourceFile = true; // default + filename = NULL; +}; + + +chillAST_TypedefDecl::chillAST_TypedefDecl(char *t, const char *a, char *p) { + underlyingtype = strdup(t); + newtype = strdup(a); + + arraypart = strdup(p); + // splitarraypart(); // TODO + + metacomment = NULL; + isStruct = isUnion = false; + structname = NULL; + rd = NULL; + isFromSourceFile = true; // default + filename = NULL; +}; + +chillAST_VarDecl *chillAST_TypedefDecl::findSubpart(const char *name) { + if (rd) { // we have a record decl look there + chillAST_VarDecl *sub = rd->findSubpart(name); + return sub; + } + + // can this ever happen now ??? + int nsub = subparts.size(); + for (int i = 0; i < nsub; i++) { + if (!strcmp(name, subparts[i]->varname)) return subparts[i]; + } + CHILL_ERROR("subpart not found\n"); + return NULL; +} + + +chillAST_RecordDecl *chillAST_TypedefDecl::getStructDef() { + if (rd) return rd; + return NULL; +} + +chillAST_RecordDecl::chillAST_RecordDecl(const char *nam, const char *orig) { + if (nam) name = strdup(nam); + else name = strdup("unknown"); // ?? + + originalname = NULL; + symbolTable = new chillAST_SymbolTable(); + if (orig) originalname = strdup(orig); + + isStruct = isUnion = false; + isFromSourceFile = true; // default + filename = NULL; +} + + +chillAST_VarDecl *chillAST_RecordDecl::findSubpart(const char *nam) { + int nsub = subparts.size(); + for (int i = 0; i < nsub; i++) { + if (!strcmp(nam, subparts[i]->varname)) return subparts[i]; + } + CHILL_DEBUG_PRINT("chillAST_RecordDecl::findSubpart() couldn't find member NAMED %s in ", nam); + print(); + return NULL; +} + + +chillAST_VarDecl *chillAST_RecordDecl::findSubpartByType(const char *typ) { + int nsub = subparts.size(); + for (int i = 0; i < nsub; i++) { + if (!strcmp(typ, subparts[i]->vartype)) return subparts[i]; + } + return NULL; +} + +chillAST_SymbolTable *chillAST_RecordDecl::addVariableToSymbolTable(chillAST_VarDecl *vd) { + // for now, just bail. or do we want the struct to have an actual symbol table? + return NULL; // damn, I hope nothing uses this! +} + +chillAST_FunctionDecl::chillAST_FunctionDecl(const char *rt, const char *fname, void *unique) { + CHILL_DEBUG_PRINT("chillAST_FunctionDecl::chillAST_FunctionDecl with unique %p\n", unique); + if (fname) + functionName = strdup(fname); + else + functionName = strdup("YouScrewedUp"); + forwarddecl = externfunc = builtin = false; + parameters = new chillAST_SymbolTable(); + this->setFunctionCPU(); + returnType = strdup(rt); + this->setFunctionCPU(); + children.push_back(new chillAST_CompoundStmt()); + uniquePtr = unique; // a quick way to check equivalence. DO NOT ACCESS THROUGH THIS +}; + +void chillAST_FunctionDecl::gatherVarDecls(vector &decls) { + for (int i = 0; i < getParameters()->size(); i++) (*getParameters())[i]->gatherVarDecls(decls); + for (int i = 0; i < children.size(); i++) children[i]->gatherVarDecls(decls); +} + + +void chillAST_FunctionDecl::gatherScalarVarDecls(vector &decls) { + for (int i = 0; i < getParameters()->size(); i++) (*getSymbolTable())[i]->gatherScalarVarDecls(decls); + for (int i = 0; i < children.size(); i++) children[i]->gatherScalarVarDecls(decls); +} + + +void chillAST_FunctionDecl::gatherArrayVarDecls(vector &decls) { + for (int i = 0; i < getParameters()->size(); i++) (*getSymbolTable())[i]->gatherArrayVarDecls(decls); + for (int i = 0; i < children.size(); i++) children[i]->gatherArrayVarDecls(decls); +} + + +chillAST_VarDecl *chillAST_FunctionDecl::findArrayDecl(const char *name) { + chillAST_VarDecl *p = getVariableDeclaration(name); + if (p && p->isArray()) return p; + chillAST_VarDecl *v = getBody()->getVariableDeclaration(name); + if (v && v->isArray()) return v; + // declared variables that may not be in symbol table but probably should be + vector decls; + gatherArrayVarDecls(decls); + for (int i = 0; i < decls.size(); i++) { + chillAST_VarDecl *vd = decls[i]; + if (0 == strcmp(vd->varname, name) && vd->isArray()) return vd; + } + return NULL; +} + +void chillAST_FunctionDecl::cleanUpVarDecls() { + vector used; + vector defined; + vector deletethese; + + gatherVarUsage(used); + gatherVarDecls(defined); + + for (int j = 0; j < defined.size(); j++) { + bool definedandused = false; + for (int i = 0; i < used.size(); i++) { + if (used[i] == defined[j]) { + definedandused = true; + break; + } + } + + if (!definedandused) { + if (!defined[j]->isParmVarDecl()) { + deletethese.push_back(defined[j]); + } + } + } + + for (int i = 0; i < deletethese.size(); i++) { + chillAST_Node *par = deletethese[i]->getParent(); + par->removeChild(par->findChild(deletethese[i])); + } + + // now check for vars used but not defined? + for (int j = 0; j < used.size(); j++) { + bool definedandused = false; + for (int i = 0; i < defined.size(); i++) { + if (used[j] == defined[i]) { + definedandused = true; + break; + } + } + if (!definedandused) { + insertChild(0, used[j]); + } + } + +} + + +bool chillAST_FunctionDecl::findLoopIndexesToReplace(chillAST_SymbolTable *symtab, bool forcesync) { + if (getBody()) getBody()->findLoopIndexesToReplace(symtab, false); + return false; +} + +chillAST_MacroDefinition::chillAST_MacroDefinition(const char *mname = NULL, const char *rhs = NULL) { + if (mname) macroName = strdup(mname); else macroName = strdup("UNDEFINEDMACRO"); + metacomment = NULL; + parameters = new chillAST_SymbolTable(); + isFromSourceFile = true; // default + filename = NULL; +}; + + +chillAST_Node *chillAST_MacroDefinition::clone() { + CHILL_ERROR("cloning a macro makes no sense\n"); + return this; + chillAST_MacroDefinition *clo = new chillAST_MacroDefinition(macroName); + clo->setParent(parent); + for (int i = 0; i < parameters->size(); i++) clo->addVariableToScope((*parameters)[i]); + clo->setBody(body->clone()); + return clo; +} + + +void chillAST_MacroDefinition::setBody(chillAST_Node *bod) { + bod->setParent(this); // well, ... +} + +chillAST_ForStmt::chillAST_ForStmt() { + children.push_back(NULL); // init + children.push_back(NULL); // cond + children.push_back(NULL); // incr + children.push_back(new chillAST_CompoundStmt()); // Body + + conditionoperator = IR_COND_UNKNOWN; + symbolTable = new chillAST_SymbolTable(); +} + + +chillAST_ForStmt::chillAST_ForStmt(chillAST_Node *ini, chillAST_Node *con, chillAST_Node *inc, chillAST_Node *bod) + : chillAST_ForStmt() { + setInit(ini); + setCond(con); + setInc(inc); + setBody(bod); + + if (!con->isBinaryOperator()) { + CHILL_ERROR("ForStmt conditional is of type %s. Expecting a BinaryOperator\n", con->getTypeString()); + exit(-1); + } + chillAST_BinaryOperator *bo = (chillAST_BinaryOperator *) con; + char *condstring = bo->op; + if (!strcmp(condstring, "<")) conditionoperator = IR_COND_LT; + else if (!strcmp(condstring, "<=")) conditionoperator = IR_COND_LE; + else if (!strcmp(condstring, ">")) conditionoperator = IR_COND_GT; + else if (!strcmp(condstring, ">=")) conditionoperator = IR_COND_GE; + else { + CHILL_ERROR("ForStmt, illegal/unhandled end condition \"%s\"\n", condstring); + CHILL_ERROR("currently can only handle <, >, <=, >=\n"); + exit(1); + } +} + +chillAST_Node *chillAST_ForStmt::clone() { + chillAST_ForStmt *fs = new chillAST_ForStmt(getInit()->clone(), getCond()->clone(), getInc()->clone(), + getBody()->clone()); + fs->isFromSourceFile = isFromSourceFile; + if (filename) fs->filename = strdup(filename); + fs->setParent(getParent()); + return fs; +} + +void chillAST_ForStmt::addSyncs() { + if (!parent) { + CHILL_ERROR("uhoh, chillAST_ForStmt::addSyncs() ForStmt has no parent!\n"); + + return; // exit? + } + + if (parent->isCompoundStmt()) { + vector *chillin = parent->getChildren(); + int numc = chillin->size(); + for (int i = 0; i < numc; i++) { + if (this == parent->getChild(i)) { + chillAST_CudaSyncthreads *ST = new chillAST_CudaSyncthreads(); + parent->insertChild(i + 1, ST); // corrupts something ... + } + } + chillin = parent->getChildren(); + int nowc = chillin->size(); + } else { + fprintf(stderr, "chillAST_ForStmt::addSyncs() unhandled parent type %s\n", parent->getTypeString()); + exit(-1); + } +} + + +void chillAST_ForStmt::removeSyncComment() { + if (metacomment && strstr(metacomment, "~cuda~") && strstr(metacomment, "preferredIdx: ")) { + char *ptr = strlen("preferredIdx: ") + strstr(metacomment, "preferredIdx: "); + *ptr = '\0'; + } +} + + +bool chillAST_ForStmt::findLoopIndexesToReplace(chillAST_SymbolTable *symtab, bool forcesync) { + CHILL_DEBUG_PRINT("\nchillAST_ForStmt::findLoopIndexesToReplace( force = %d )\n", forcesync); + bool force = forcesync; + bool didasync = false; + if (forcesync) { + addSyncs(); + didasync = true; + } + if (metacomment && strstr(metacomment, "~cuda~") && strstr(metacomment, "preferredIdx: ")) { + char *copy = strdup(metacomment); + char *ptr = strstr(copy, "preferredIdx: "); + char *vname = ptr + strlen("preferredIdx: "); + char *space = strstr(vname, " "); // TODO index() + if (space) + force = true; + if ((!didasync) && force) { + addSyncs(); + removeSyncComment(); + didasync = true; + } + + if (space) *space = '\0'; // if this is multiple words, grab the first one + + vector decls; + getInit()->gatherVarLHSUsage(decls); + //cond->gatherVarUsage( decls ); + //incr->gatherVarUsage( decls ); + + if (1 != decls.size()) { + CHILL_ERROR("uhoh, preferred index in for statement, but multiple variables used\n"); + print(0, stderr); + fprintf(stderr, "\nvariables are:\n"); + for (int i = 0; i < decls.size(); i++) { + decls[i]->print(0, stderr); + fprintf(stderr, "\n"); + } + exit(0); + } + chillAST_VarDecl *olddecl = decls[0]; + + // RIGHT NOW, change all the references that this loop wants swapped out + // find vardecl for named preferred index. it has to already exist + chillAST_VarDecl *newguy = findVariableDecleration(vname); // recursive + if (!newguy) + CHILL_ERROR("there was no variable named %s anywhere I could find\n", vname); + + // wrong - this only looks at variables defined in the forstmt, not + // in parents of the forstmt + if (!newguy) { + CHILL_DEBUG_PRINT("chillAST_ForStmt::findLoopIndexesToReplace() there is no defined variable %s\n", vname); + + // make one ?? seems like this should never happen + newguy = new chillAST_VarDecl(olddecl->vartype, vname, ""/*?*/, NULL); + // insert actual declaration in code location? how? + + // find parent of the ForStmt? + // find parent^n of the ForStmt that is not a Forstmt? + // find parent^n of the Forstmt that is a FunctionDecl? + chillAST_Node *contain = findContainingNonLoop(); + if (contain == NULL) { + CHILL_ERROR("nothing but loops all the way up?\n"); + exit(0); + } + contain->print(0, stderr); + contain->insertChild(0, newguy); // TODO ugly order + contain->addVariableToScope(newguy); // adds to first enclosing symbolTable + + if (!symbolTableFindName(contain->getSymbolTable(), vname)) { + CHILL_ERROR("container doesn't have a var names %s afterwards???\n", vname); + exit(-1); + } + } + // swap out old for new in init, cond, incr, body + if (newguy) + replaceVarDecls(olddecl, newguy); + metacomment = NULL; // memleak + } + // check for more loops. We may have already swapped variables out in body (right above here) + getBody()->findLoopIndexesToReplace(symtab, false); + return force; +} + +void chillAST_ForStmt::gatherLoopIndeces(std::vector &indeces) { + vector decls; + getInit()->gatherVarLHSUsage(decls); + getCond()->gatherVarLHSUsage(decls); + getInc()->gatherVarLHSUsage(decls); + // note: NOT GOING INTO BODY OF THE LOOP + + int numdecls = decls.size(); + for (int i = 0; i < decls.size(); i++) + indeces.push_back(decls[i]); + + // Don't forget to keep heading upwards! + if (parent) + parent->gatherLoopIndeces(indeces); +} + + +void chillAST_ForStmt::gatherLoopVars(std::vector &loopvars) { + vector decls; + getInit()->gatherVarLHSUsage(decls); + getCond()->gatherVarLHSUsage(decls); + getInc()->gatherVarLHSUsage(decls); + // note: NOT GOING INTO BODY OF THE LOOP + for (int i = 0; i < decls.size(); i++) loopvars.push_back(strdup(decls[i]->varname)); +} + + +void chillAST_ForStmt::loseLoopWithLoopVar(char *var) { + + //fprintf(stderr, "\nchillAST_ForStmt::loseLoopWithLoopVar( %s )\n", var ); + + // now recurse (could do first, I suppose) + // if you DON'T do this first, you may have already replaced yourself with this loop body + // the body will no longer have this forstmt as parent, it will have the forstmt's parent as its parent + //fprintf(stderr, "forstmt 0x%x, recursing loseLoop to body 0x%x of type %s with parent 0x%x of type %s\n", this, body, body->getTypeString(), body->parent, body->parent->getTypeString()); + getBody()->loseLoopWithLoopVar(var); + + + + + // if *I* am a loop to be replaced, tell my parent to replace me with my loop body + + std::vector loopvars; + gatherLoopVars(loopvars); + + if (loopvars.size() != 1) { + fprintf(stderr, "uhoh, loop has more than a single loop var and trying to loseLoopWithLoopVar()\n"); + print(0, stderr); + fprintf(stderr, "\nvariables are:\n"); + for (int i = 0; i < loopvars.size(); i++) { + fprintf(stderr, "%s\n", loopvars[i].c_str()); + } + + exit(-1); + } + + //fprintf(stderr, "my loop var %s, looking for %s\n", loopvars[0].c_str(), var ); + if (!strcmp(var, loopvars[0].c_str())) { + //fprintf(stderr, "OK, trying to lose myself! for ("); + //init->print(0, stderr); + //fprintf(stderr, "; "); + //cond->print(0, stderr); + //fprintf(stderr, "; "); + //incr->print(0, stderr); + //fprintf(stderr, ")\n" ); + + if (!parent) { + fprintf(stderr, "chillAST_ForStmt::loseLoopWithLoopVar() I have no parent!\n"); + exit(-1); + } + + vector decls; + getInit()->gatherVarLHSUsage(decls); // this can fail if init is outside the loop + getCond()->gatherVarLHSUsage(decls); + getInc()->gatherVarLHSUsage(decls); + if (decls.size() > 1) { + fprintf(stderr, "chill_ast.cc multiple loop variables confuses me\n"); + exit(-1); + } + chillAST_Node *newstmt = getBody(); + + // ACTUALLY, if I am being replaced, and my loop conditional is a min (Ternary), then wrap my loop body in an if statement + if (getCond()->isBinaryOperator()) { // what else could it be? + chillAST_BinaryOperator *BO = (chillAST_BinaryOperator *) getCond(); + if (BO->getRHS()->isTernaryOperator()) { + + chillAST_TernaryOperator *TO = (chillAST_TernaryOperator *) BO->getRHS(); + chillAST_BinaryOperator *C = (chillAST_BinaryOperator *) TO->getCond(); + + //fprintf(stderr, "loop condition RHS is ternary\nCondition RHS"); + C->print(); + chillAST_Node *l = C->getLHS(); + if (l->isParenExpr()) l = ((chillAST_ParenExpr *) l)->getSubExpr(); + chillAST_Node *r = C->getRHS(); + if (r->isParenExpr()) r = ((chillAST_ParenExpr *) r)->getSubExpr(); + + //fprintf(stderr, "lhs is %s rhs is %s\n", l->getTypeString(), r->getTypeString()); + + chillAST_Node *ifcondrhs = NULL; + if (!(l->isConstant())) ifcondrhs = l; + else if (!(r->isConstant())) ifcondrhs = r; + else { + // should never happen. 2 constants. infinite loop + fprintf(stderr, "chill_ast.cc INIFNITE LOOP?\n"); + this->print(0, stderr); + fprintf(stderr, "\n\n"); + exit(-1); + } + + // wrap the loop body in an if + chillAST_DeclRefExpr *DRE = new chillAST_DeclRefExpr(decls[0]); + chillAST_BinaryOperator *ifcond = new chillAST_BinaryOperator(DRE, "<=", ifcondrhs); + chillAST_IfStmt *ifstmt = new chillAST_IfStmt(ifcond, getBody(), NULL); + + newstmt = ifstmt; + } + } + + //fprintf(stderr, "forstmt 0x%x has parent 0x%x of type %s\n", this, parent, parent->getTypeString()); + //fprintf(stderr, "forstmt will be replaced by\n"); + //newstmt->print(0,stderr); fprintf(stderr, "\n\n"); + + parent->replaceChild(this, newstmt); + } + + +} + +chillAST_BinaryOperator::chillAST_BinaryOperator() { + children.push_back(NULL); + children.push_back(NULL); +} + +chillAST_BinaryOperator::chillAST_BinaryOperator(chillAST_Node *l, const char *oper, chillAST_Node *r) + : chillAST_BinaryOperator() { + CHILL_DEBUG_PRINT("( l %s r )\n", oper); + + setLHS(l); + setRHS(r); + + if (oper) op = strdup(oper); + + // if this writes to lhs and lhs type has an 'imwrittento' concept, set that up + if (isAssignmentOp()) { + if (l && l->isArraySubscriptExpr()) { + ((chillAST_ArraySubscriptExpr *) l)->imwrittento = true; + } + } + if (isAugmentedAssignmentOp()) { // += etc + if (l && l->isArraySubscriptExpr()) { + ((chillAST_ArraySubscriptExpr *) l)->imreadfrom = true; // note will ALSO have imwrittento true + } + } + + isFromSourceFile = true; // default + filename = NULL; +} + + +int chillAST_BinaryOperator::evalAsInt() { + // very limited. allow +-*/ and integer literals ... + if (isAssignmentOp()) return getRHS()->evalAsInt(); // ?? ignores/loses lhs info + + if (!strcmp("+", op)) { + //fprintf(stderr, "chillAST_BinaryOperator::evalAsInt() %d + %d\n", lhs->evalAsInt(), rhs->evalAsInt()); + return getLHS()->evalAsInt() + getRHS()->evalAsInt(); + } + if (!strcmp("-", op)) return getLHS()->evalAsInt() - getRHS()->evalAsInt(); + if (!strcmp("*", op)) return getLHS()->evalAsInt() * getRHS()->evalAsInt(); + if (!strcmp("/", op)) return getLHS()->evalAsInt() / getRHS()->evalAsInt(); + + fprintf(stderr, "chillAST_BinaryOperator::evalAsInt() unhandled op '%s'\n", op); + exit(-1); +} + +chillAST_IntegerLiteral *chillAST_BinaryOperator::evalAsIntegerLiteral() { + return new chillAST_IntegerLiteral(evalAsInt()); // ?? +} + +class chillAST_Node *chillAST_BinaryOperator::constantFold() { + chillAST_Node::constantFold(); + + chillAST_Node *returnval = this; + + if (getLHS()->isConstant() && getRHS()->isConstant()) { + if (!strcmp(op, "+") || !strcmp(op, "-") || !strcmp(op, "*")) { + if (getLHS()->isIntegerLiteral() && getRHS()->isIntegerLiteral()) { + chillAST_IntegerLiteral *l = (chillAST_IntegerLiteral *) getLHS(); + chillAST_IntegerLiteral *r = (chillAST_IntegerLiteral *) getRHS(); + chillAST_IntegerLiteral *I; + + if (!strcmp(op, "+")) I = new chillAST_IntegerLiteral(l->value + r->value); + if (!strcmp(op, "-")) I = new chillAST_IntegerLiteral(l->value - r->value); + if (!strcmp(op, "*")) I = new chillAST_IntegerLiteral(l->value * r->value); + + returnval = I; + } else { + + // usually don't want to do this for floats or doubles + // could probably check for special cases like 0.0/30.0 or X/X or X/1.0 + double lval, rval; + int prec = 1; + if (getLHS()->isIntegerLiteral()) + lval = ((chillAST_IntegerLiteral *)getLHS())->value; + else { + lval = ((chillAST_FloatingLiteral *)getLHS())->value; + prec = max(prec, ((chillAST_FloatingLiteral *)getLHS())->getPrecision()); + } + + if (getRHS()->isIntegerLiteral()) + rval = ((chillAST_IntegerLiteral *)getRHS())->value; + else { + rval = ((chillAST_FloatingLiteral *) getRHS())->value; + prec = max(prec, ((chillAST_FloatingLiteral *) getRHS())->getPrecision()); + } + + chillAST_FloatingLiteral *F; + // NOT SAFE + // if (streq(op, "+")) F = new chillAST_FloatingLiteral(lval + rval, parent); + // if (streq(op, "-")) F = new chillAST_FloatingLiteral(lval - rval, parent); + if (streq(op, "*")) F = new chillAST_FloatingLiteral(lval * rval, prec, NULL); + + returnval = F; + + } + } + //else fprintf(stderr, "can't fold op '%s' yet\n", op); + } + + //fprintf(stderr, "returning "); returnval->print(0,stderr); fprintf(stderr, "\n"); + return returnval; +} + + +class chillAST_Node *chillAST_BinaryOperator::clone() { + //fprintf(stderr, "chillAST_BinaryOperator::clone() "); print(); printf("\n"); fflush(stdout); + + chillAST_Node *l = getLHS()->clone(); + chillAST_Node *r = getRHS()->clone(); + chillAST_BinaryOperator *bo = new chillAST_BinaryOperator(l, op, r); + l->setParent(bo); + r->setParent(bo); + bo->isFromSourceFile = isFromSourceFile; + if (filename) bo->filename = strdup(filename); + return bo; +} + +void chillAST_BinaryOperator::gatherArrayRefs(std::vector &refs, bool w) { + getLHS()->gatherArrayRefs(refs, isAssignmentOp()); + getRHS()->gatherArrayRefs(refs, 0); +} + +void chillAST_BinaryOperator::gatherScalarRefs(std::vector &refs, bool writtento) { + getLHS()->gatherScalarRefs(refs, isAssignmentOp()); + getRHS()->gatherScalarRefs(refs, 0); +} + +void chillAST_BinaryOperator::gatherVarLHSUsage(vector &decls) { + getLHS()->gatherVarUsage(decls); +} + +chillAST_TernaryOperator::chillAST_TernaryOperator() { + op = strdup("?"); + children.push_back(NULL); + children.push_back(NULL); + children.push_back(NULL); +} + +chillAST_TernaryOperator::chillAST_TernaryOperator(const char *oper, chillAST_Node *c, chillAST_Node *l, + chillAST_Node *r) : chillAST_TernaryOperator() { + if (op) op = strdup(oper); + setCond(c); + setLHS(l); + setRHS(r); +} + +void chillAST_TernaryOperator::gatherVarLHSUsage(vector &decls) { + // this makes no sense for ternary ?? +} + +class chillAST_Node *chillAST_TernaryOperator::constantFold() { + chillAST_Node::constantFold(); + + chillAST_Node *returnval = this; + + if (getCond()->isConstant()) { + // TODO + } + + return returnval; +} + +class chillAST_Node *chillAST_TernaryOperator::clone() { + chillAST_Node *c = getCond()->clone(); + chillAST_Node *l = getLHS()->clone(); + chillAST_Node *r = getRHS()->clone(); + chillAST_TernaryOperator *to = new chillAST_TernaryOperator(op, c, l, r); + to->isFromSourceFile = isFromSourceFile; + filename = NULL; + return to; +} + +chillAST_ArraySubscriptExpr::chillAST_ArraySubscriptExpr() { + children.push_back(NULL); // Base + children.push_back(NULL); // Index + basedecl = NULL; +} + +chillAST_ArraySubscriptExpr::chillAST_ArraySubscriptExpr(chillAST_Node *bas, chillAST_Node *indx, bool writtento, + void *unique):chillAST_ArraySubscriptExpr() { + imwrittento = writtento; // ?? + imreadfrom = false; // ?? + if (bas) { + if (bas->isImplicitCastExpr()) setBase(((chillAST_ImplicitCastExpr *) bas)->getSubExpr()); // probably wrong + else setBase(bas); + basedecl = multibase(); + } + if (indx) { + if (indx->isImplicitCastExpr()) setIndex(((chillAST_ImplicitCastExpr *) indx)->getSubExpr()); // probably wrong + else setIndex(indx); + } + uniquePtr = unique; +} + +chillAST_ArraySubscriptExpr::chillAST_ArraySubscriptExpr(chillAST_VarDecl *v, std::vector indeces):chillAST_ArraySubscriptExpr() { + int numindeces = indeces.size(); + for (int i = 0; i < numindeces; i++) { + fprintf(stderr, "ASE index %d ", i); + indeces[i]->print(0, stderr); + fprintf(stderr, "\n"); + } + chillAST_DeclRefExpr *DRE = new chillAST_DeclRefExpr(v->vartype, v->varname, v); + basedecl = v; // ?? + + chillAST_ArraySubscriptExpr *rent = this; // parent for subnodes + + // these are on the top level ASE that we're creating here + setBase(DRE); + setIndex(indeces[numindeces - 1]); + + for (int i = numindeces - 2; i >= 0; i--) { + + chillAST_ArraySubscriptExpr *ASE = new chillAST_ArraySubscriptExpr(DRE, indeces[i], rent, 0); + rent->setBase(ASE); + } + + imwrittento = false; + imreadfrom = false; + isFromSourceFile = true; + filename = NULL; +} + +void chillAST_ArraySubscriptExpr::gatherIndeces(std::vector &ind) { + if (getBase()->isArraySubscriptExpr()) ((chillAST_ArraySubscriptExpr*)getBase())->gatherIndeces(ind); + ind.push_back(getIndex()); +} + +chillAST_VarDecl *chillAST_ArraySubscriptExpr::multibase() { + return getBase()->multibase(); +} + + +chillAST_Node *chillAST_ArraySubscriptExpr::getIndex(int dim) { + CHILL_DEBUG_PRINT("chillAST_ArraySubscriptExpr::getIndex( %d )\n", dim); + chillAST_Node *b = getBase(); + int depth = 0; + std::vector ind; + chillAST_Node *curindex = getIndex(); + for (;;) { + if (b->getType() == CHILLAST_NODE_IMPLICITCASTEXPR) + b = ((chillAST_ImplicitCastExpr *) b)->getSubExpr(); + else if (b->getType() == CHILLAST_NODE_ARRAYSUBSCRIPTEXPR) { + ind.push_back(curindex); + curindex = ((chillAST_ArraySubscriptExpr *) b)->getIndex(); + b = ((chillAST_ArraySubscriptExpr *) b)->getBase(); + depth++; + } else { + ind.push_back(curindex); + break; + } + } + return ind[depth - dim]; +} + +class chillAST_Node *chillAST_ArraySubscriptExpr::clone() { + chillAST_Node *b = getBase()->clone(); + chillAST_Node *i = getIndex()->clone(); + chillAST_ArraySubscriptExpr *ASE = new chillAST_ArraySubscriptExpr(b, i, imwrittento, uniquePtr); + ASE->setParent(parent); + ASE->imreadfrom = false; // don't know this yet + ASE->isFromSourceFile = isFromSourceFile; + if (filename) ASE->filename = strdup(filename); + return ASE; +} + +void chillAST_ArraySubscriptExpr::gatherArrayRefs(std::vector &refs, bool writtento) { + if (!imwrittento) imwrittento = writtento; // may be both written and not for += TODO Purpose unclear + getIndex()->gatherArrayRefs(refs, 0); // recurse first + refs.push_back(this); +} + +void chillAST_ArraySubscriptExpr::gatherScalarRefs(std::vector &refs, bool writtento) { + chillAST_Node::gatherScalarRefs(refs, false); +} + +bool chillAST_ArraySubscriptExpr::operator!=(const chillAST_ArraySubscriptExpr &other) { + bool opposite = *this == other; + return !opposite; +} + + +bool chillAST_ArraySubscriptExpr::operator==(const chillAST_ArraySubscriptExpr &other) { + return this->uniquePtr == other.uniquePtr; +} + +chillAST_MemberExpr::chillAST_MemberExpr() { + children.push_back(NULL); +} +chillAST_MemberExpr::chillAST_MemberExpr(chillAST_Node *bas, const char *mem, void *unique, + CHILLAST_MEMBER_EXP_TYPE t):chillAST_MemberExpr() { + setBase(bas); + if (mem) member = strdup(mem); + else + member = NULL; + uniquePtr = unique; + exptype = t; + + return; +} + +// TODO member can be another member expression, Right? + +class chillAST_Node *chillAST_MemberExpr::clone() { + chillAST_Node *b = getBase()->clone(); + char *m = strdup(member); + chillAST_MemberExpr *ME = new chillAST_MemberExpr(b, m, uniquePtr); + ME->isFromSourceFile = isFromSourceFile; + if (filename) ME->filename = strdup(filename); + return ME; +} + +bool chillAST_MemberExpr::operator!=(const chillAST_MemberExpr &other) { + bool opposite = *this == other; + return !opposite; +} + +bool chillAST_MemberExpr::operator==(const chillAST_MemberExpr &other) { + return this->uniquePtr == other.uniquePtr; +} + +chillAST_Node *chillAST_MemberExpr::multibase2() { /*fprintf(stderr, "ME MB2\n" );*/ return (chillAST_Node *) this; } + +chillAST_VarDecl *chillAST_MemberExpr::getUnderlyingVarDecl() { + CHILL_ERROR("chillAST_MemberExpr:getUnderlyingVarDecl()\n"); + print(); + exit(-1); + // find the member with the correct name + +} + + +chillAST_VarDecl *chillAST_MemberExpr::multibase() { + chillAST_VarDecl *vd = getBase()->multibase(); // ?? + + chillAST_RecordDecl *rd = vd->getStructDef(); + if (!rd) { + fprintf(stderr, "chillAST_MemberExpr::multibase() vardecl is not a struct??\n"); + fprintf(stderr, "vd "); + vd->print(); + fprintf(stderr, "vd "); + vd->dump(); + exit(-1); + } + // OK, we have the recorddecl that defines the structure + // now find the member with the correct name + chillAST_VarDecl *sub = rd->findSubpart(member); + if (!sub) { + fprintf(stderr, "can't find member %s in \n", member); + rd->print(); + } + return sub; +} + +chillAST_DeclRefExpr::chillAST_DeclRefExpr(const char *vartype, const char *varname, chillAST_Node *d) { + if (vartype) declarationType = strdup(vartype); + else declarationType = strdup("UNKNOWN"); + if (varname) declarationName = strdup(varname); + else declarationName = strdup("NONE"); + decl = d; +} + +chillAST_DeclRefExpr::chillAST_DeclRefExpr(chillAST_VarDecl *vd) { + declarationType = strdup(vd->vartype); + declarationName = strdup(vd->varname); + decl = vd; +} + + +chillAST_DeclRefExpr::chillAST_DeclRefExpr(chillAST_FunctionDecl *fd) { + declarationType = strdup(fd->returnType); + declarationName = strdup(fd->functionName); + decl = fd; +} + +class chillAST_Node *chillAST_DeclRefExpr::clone() { + chillAST_DeclRefExpr *DRE = new chillAST_DeclRefExpr(declarationType, declarationName, decl); + DRE->setParent(parent); + DRE->isFromSourceFile = isFromSourceFile; + if (filename) DRE->filename = strdup(filename); + return DRE; +} + + +void chillAST_DeclRefExpr::gatherVarDeclsMore(vector &decls) { + decl->gatherVarDeclsMore(decls); +} + +void chillAST_DeclRefExpr::gatherDeclRefExprs(vector &refs) { + refs.push_back(this); +} + +void chillAST_DeclRefExpr::gatherScalarRefs(std::vector &refs, bool writtento) { + refs.push_back(this); +} + +void chillAST_DeclRefExpr::gatherVarUsage(vector &decls) { + for (int i = 0; i < decls.size(); i++) { + if (decls[i] == decl) { + return; + } + if (streq(declarationName, decls[i]->varname)) { + if (streq(declarationType, decls[i]->vartype)) { + CHILL_ERROR("Deprecated\n"); + return; + } + } + } + chillAST_VarDecl *vd = getVarDecl(); // null for functiondecl + if (vd) decls.push_back(vd); +} + + +void chillAST_DeclRefExpr::replaceVarDecls(chillAST_VarDecl *olddecl, chillAST_VarDecl *newdecl) { + if (decl == olddecl) { + decl = newdecl; + declarationType = strdup(newdecl->vartype); + declarationName = strdup(newdecl->varname); + } else { + CHILL_ERROR("Deprecated\n"); + if (!strcmp(olddecl->varname, declarationName)) { + decl = newdecl; + declarationType = strdup(newdecl->vartype); + declarationName = strdup(newdecl->varname); + } + } +} + +chillAST_VarDecl *chillAST_ImplicitCastExpr::multibase() { + return getSubExpr()->multibase(); +} + + +chillAST_VarDecl *chillAST_DeclRefExpr::multibase() { + // presumably, this is being called because this DRE is the base of an ArraySubscriptExpr + return getVarDecl(); +} + + +void chillAST_VarDecl::gatherVarDecls(vector &decls) { + for (int i = 0; i < decls.size(); i++) { + if (decls[i] == this) { + return; + } + if (streq(decls[i]->varname, varname)) { + if (streq(decls[i]->vartype, vartype)) { + CHILL_ERROR("Wrong\n"); + return; + } + } + } + decls.push_back(this); +} + + +void chillAST_VarDecl::gatherScalarVarDecls(vector &decls) { + if (numdimensions != 0) return; // not a scalar + + for (int i = 0; i < decls.size(); i++) { + if (decls[i] == this) { + return; + } + if (streq(decls[i]->varname, varname)) { // wrong. scoping. TODO + if (streq(decls[i]->vartype, vartype)) { + CHILL_ERROR("Wrong\n"); + return; + } + } + } + decls.push_back(this); +} + + +void chillAST_VarDecl::gatherArrayVarDecls(vector &decls) { + if (numdimensions == 0) return; // not an array + + for (int i = 0; i < decls.size(); i++) { + if (decls[i] == this) { + return; + } + + if (streq(decls[i]->varname, varname)) { // wrong. scoping. TODO + if (streq(decls[i]->vartype, vartype)) { + CHILL_ERROR("Wrong\n"); + return; + } + } + } + decls.push_back(this); +} + + +chillAST_Node *chillAST_VarDecl::clone() { + chillAST_VarDecl *vd = new chillAST_VarDecl(vartype, strdup(varname), arraypart, + NULL); // NULL so we don't add the variable AGAIN to the (presumably) function + + vd->typedefinition = typedefinition; + vd->vardef = vardef; // perhaps should not do this TODO + //vd->isStruct = (vardef != NULL); // ?? + + vd->underlyingtype = strdup(underlyingtype); + + vd->arraysizes = NULL; + vd->knownArraySizes = knownArraySizes; + vd->numdimensions = numdimensions; + vd->arraypointerpart = NULL; + + if (arraypart != NULL && NULL != arraysizes) { // !strcmp(arraypart, "")) { + vd->numdimensions = numdimensions; + + if (arraysizes) { + vd->arraysizes = (int *) malloc(sizeof(int *) * numdimensions); + for (int i = 0; i < numdimensions; i++) + vd->arraysizes[i] = arraysizes[i]; + } + } + + if (arraypointerpart) + vd->arraypointerpart = strdup(arraypointerpart); + + vd->isStruct = this->isStruct; + vd->knownArraySizes = this->knownArraySizes; + vd->isFromSourceFile = isFromSourceFile; + if (filename) vd->filename = strdup(filename); + return vd; +} + + +void chillAST_VarDecl::splitarraypart() { + if (arraypart) CHILL_DEBUG_PRINT("%s\n", arraypart); + + // split arraypart into (leading??) asterisks and known sizes [1][2][3] + if (!arraypart || // NULL + (arraypart && (*arraypart == '\0'))) { // or empty string + + // parts are both empty string + if (arraypointerpart) free(arraypointerpart); + arraypointerpart = strdup(""); + if (arraysetpart) free(arraysetpart); + arraysetpart = strdup(""); + return; + } + + // arraypart exists and is not empty + int asteriskcount = 0; + int fixedcount = 0; + for (int i = 0; i < strlen(arraypart); i++) { + if (arraypart[i] == '*') { + if (fixedcount) { + CHILL_ERROR("illegal vardecl arraypart: '%s'\n", arraypart); + exit(-1); + exit(-1); + } + asteriskcount++; + } else { // remainder is fixed? + fixedcount++; + // check for brackets and digits only? TODO + } + } + arraypointerpart = (char *) calloc(asteriskcount + 1, sizeof(char)); + arraysetpart = (char *) calloc(fixedcount + 1, sizeof(char)); + char *ptr = arraypart; + for (int i = 0; i < asteriskcount; i++) arraypointerpart[i] = *ptr++; + for (int i = 0; i < fixedcount; i++) arraysetpart[i] = *ptr++; +} + + +chillAST_IntegerLiteral::chillAST_IntegerLiteral(int val) { + value = val; + isFromSourceFile = true; // default + filename = NULL; +} + +class chillAST_Node *chillAST_IntegerLiteral::clone() { + + chillAST_IntegerLiteral *IL = new chillAST_IntegerLiteral(value); + IL->isFromSourceFile = isFromSourceFile; + if (filename) IL->filename = strdup(filename); + return IL; + +} + +chillAST_FloatingLiteral::chillAST_FloatingLiteral(double val, int precis, const char *printthis) { + value = val; + precision = precis; + allthedigits = NULL; + if (printthis) + allthedigits = strdup(printthis); + isFromSourceFile = true; + filename = NULL; +} + + +chillAST_FloatingLiteral::chillAST_FloatingLiteral(chillAST_FloatingLiteral *old) { + value = old->value; + allthedigits = NULL; + if (old->allthedigits) allthedigits = strdup(old->allthedigits); + precision = old->precision; + isFromSourceFile = true; // default + filename = NULL; +} + +chillAST_Node *chillAST_FloatingLiteral::clone() { + chillAST_FloatingLiteral *newone = new chillAST_FloatingLiteral(this); + newone->isFromSourceFile = isFromSourceFile; + if (filename) newone->filename = strdup(filename); + return newone; +} + +chillAST_UnaryOperator::chillAST_UnaryOperator() { + children.push_back(NULL); +} + +chillAST_UnaryOperator::chillAST_UnaryOperator(const char *oper, bool pre, chillAST_Node *sub) + : chillAST_UnaryOperator() { + op = strdup(oper); + prefix = pre; + setSubExpr(sub); + isFromSourceFile = true; // default + filename = NULL; +} + +void chillAST_UnaryOperator::gatherArrayRefs(std::vector &refs, bool w) { + getSubExpr()->gatherArrayRefs(refs, isAssignmentOp()); // +} + +void chillAST_UnaryOperator::gatherVarLHSUsage(vector &decls) { + if (isAssignmentOp()) { + getSubExpr()->gatherVarUsage(decls); // do all unary modify the subexpr? (no, - ) + } +} + + +chillAST_Node *chillAST_UnaryOperator::constantFold() { + chillAST_Node::constantFold(); + + chillAST_Node *returnval = this; + if (getSubExpr()->isConstant()) { + if (streq(op, "-")) { + if (getSubExpr()->isIntegerLiteral()) { + int intval = ((chillAST_IntegerLiteral *) getSubExpr())->value; + chillAST_IntegerLiteral *I = new chillAST_IntegerLiteral(-intval); + I->setParent(parent); + returnval = I; + } else { + chillAST_FloatingLiteral *FL = (chillAST_FloatingLiteral *) getSubExpr(); + chillAST_FloatingLiteral *F = (chillAST_FloatingLiteral*)(FL->clone()); // clone + F->value = -F->value; + returnval = F; + } + } else CHILL_DEBUG_PRINT("can't fold op '%s' yet\n", op); + } + return returnval; +} + + +class chillAST_Node *chillAST_UnaryOperator::clone() { + chillAST_UnaryOperator *UO = new chillAST_UnaryOperator(op, prefix, getSubExpr()->clone()); + UO->setParent(parent); + UO->isFromSourceFile = isFromSourceFile; + if (filename) UO->filename = strdup(filename); + return UO; +} + +int chillAST_UnaryOperator::evalAsInt() { + if (!strcmp("+", op)) return getSubExpr()->evalAsInt(); + if (!strcmp("-", op)) return -getSubExpr()->evalAsInt(); + if (!strcmp("++", op)) return 1 + getSubExpr()->evalAsInt(); + if (!strcmp("--", op)) return getSubExpr()->evalAsInt() - 1; + + fprintf(stderr, "chillAST_UnaryOperator::evalAsInt() unhandled op '%s'\n", op); + exit(-1); +} + +chillAST_ImplicitCastExpr::chillAST_ImplicitCastExpr() { + children.push_back(NULL); +} + +chillAST_Node* chillAST_ImplicitCastExpr::constantFold() { + chillAST_Node::constantFold(); + return getSubExpr(); +} + +chillAST_ImplicitCastExpr::chillAST_ImplicitCastExpr(chillAST_Node *sub) : chillAST_ImplicitCastExpr() { + setSubExpr(sub); +} + +class chillAST_Node *chillAST_ImplicitCastExpr::clone() { + chillAST_ImplicitCastExpr *ICE = new chillAST_ImplicitCastExpr(getSubExpr()->clone()); + ICE->isFromSourceFile = isFromSourceFile; + if (filename) ICE->filename = strdup(filename); + return ICE; +} + +chillAST_CStyleCastExpr::chillAST_CStyleCastExpr() { + children.push_back(NULL); +} + +chillAST_CStyleCastExpr::chillAST_CStyleCastExpr(const char *to, chillAST_Node *sub) : chillAST_CStyleCastExpr() { + towhat = strdup(to); + setSubExpr(sub); +} + +chillAST_Node * chillAST_CStyleCastExpr::constantFold() { + chillAST_Node::constantFold(); + if (getSubExpr()->isConstant()) { + double val; + if (getSubExpr() -> isIntegerLiteral()) { + val = getSubExpr()->evalAsInt(); + } else if (getSubExpr() -> isFloatingLiteral()) { + val = ((chillAST_FloatingLiteral*)getSubExpr())->value; + } else return this; + if (!strcmp(towhat,"float")) + return new chillAST_FloatingLiteral(val,1,NULL); + if (!strcmp(towhat, "double")) + return new chillAST_FloatingLiteral(val,2,NULL); + } + return this; +} + +class chillAST_Node *chillAST_CStyleCastExpr::clone() { + chillAST_CStyleCastExpr *CSCE = new chillAST_CStyleCastExpr(towhat, getSubExpr()->clone()); + CSCE->setParent(getParent()); + CSCE->isFromSourceFile = isFromSourceFile; + if (filename) CSCE->filename = strdup(filename); + return CSCE; +} + +chillAST_CStyleAddressOf::chillAST_CStyleAddressOf() { + children.push_back(NULL); +} + +chillAST_CStyleAddressOf::chillAST_CStyleAddressOf(chillAST_Node *sub) : chillAST_CStyleAddressOf() { + setSubExpr(sub); +} + +class chillAST_Node *chillAST_CStyleAddressOf::clone() { + chillAST_CStyleAddressOf *CSAO = new chillAST_CStyleAddressOf(getSubExpr()->clone()); + CSAO->setParent(getParent()); + CSAO->isFromSourceFile = isFromSourceFile; + if (filename) CSAO->filename = strdup(filename); + return CSAO; +} + +chillAST_Malloc::chillAST_Malloc() { + children.push_back(NULL); +} + +chillAST_Malloc::chillAST_Malloc(chillAST_Node *numthings) : chillAST_Malloc() { + setSize(numthings); + isFromSourceFile = true; // default + filename = NULL; +}; + +chillAST_Node *chillAST_Malloc::clone() { + chillAST_Malloc *M = new chillAST_Malloc(getSize()->clone()); // the general version + M->setParent(getParent()); + M->isFromSourceFile = isFromSourceFile; + if (filename) M->filename = strdup(filename); + return M; +}; + +chillAST_CudaMalloc::chillAST_CudaMalloc() { + children.push_back(NULL); + children.push_back(NULL); +} + +chillAST_CudaMalloc::chillAST_CudaMalloc(chillAST_Node *devmemptr, chillAST_Node *size) : chillAST_CudaMalloc() { + setDevPtr(devmemptr); + setSize(size); +}; + +class chillAST_Node *chillAST_CudaMalloc::clone() { + chillAST_CudaMalloc *CM = new chillAST_CudaMalloc(getDevPtr()->clone(), getSize()->clone()); + CM->setParent(getParent()); + CM->isFromSourceFile = isFromSourceFile; + if (filename) CM->filename = strdup(filename); + return CM; +} + +void chillAST_CudaMalloc::gatherArrayRefs(std::vector &refs, bool w) { + chillAST_Node::gatherArrayRefs(refs, false); +} + +void chillAST_CudaMalloc::gatherScalarRefs(std::vector &refs, bool writtento) { + chillAST_Node::gatherScalarRefs(refs, false); +} + +chillAST_CudaFree::chillAST_CudaFree() { + children.push_back(NULL); +} + +chillAST_CudaFree::chillAST_CudaFree(chillAST_Node *var) : chillAST_CudaFree() { + setParent(var); +}; + +class chillAST_Node *chillAST_CudaFree::clone() { + chillAST_CudaFree *CF = new chillAST_CudaFree(getPointer()->clone()); + CF->setParent(getParent()); + CF->isFromSourceFile = isFromSourceFile; + if (filename) CF->filename = strdup(filename); + return CF; +} + +chillAST_CudaMemcpy::chillAST_CudaMemcpy() { + addChild(NULL); + addChild(NULL); + addChild(NULL); +} + +chillAST_CudaMemcpy::chillAST_CudaMemcpy(chillAST_Node *d, chillAST_Node *s, chillAST_Node *siz, char *kind) { + setDest(d); + setSrc(s); + setSize(siz); + cudaMemcpyKind = kind; +}; + +class chillAST_Node *chillAST_CudaMemcpy::clone() { + chillAST_CudaMemcpy *CMCPY = new chillAST_CudaMemcpy(getDest()->clone(), + getSrc()->clone(), getSize()->clone(), + strdup(cudaMemcpyKind)); + CMCPY->setParent(getParent()); + CMCPY->isFromSourceFile = isFromSourceFile; + if (filename) CMCPY->filename = strdup(filename); + return CMCPY; +} + +void chillAST_CudaMemcpy::gatherArrayRefs(std::vector &refs, bool w) { + chillAST_Node::gatherArrayRefs(refs, false); +} + +void chillAST_CudaMemcpy::gatherScalarRefs(std::vector &refs, bool writtento) { + chillAST_Node::gatherScalarRefs(refs, false); +} + +chillAST_CudaSyncthreads::chillAST_CudaSyncthreads() { +} + +chillAST_ReturnStmt::chillAST_ReturnStmt() { + children.push_back(NULL); +} + +chillAST_ReturnStmt::chillAST_ReturnStmt(chillAST_Node *retval) : chillAST_ReturnStmt() { + setRetVal(retval); +} + +class chillAST_Node *chillAST_ReturnStmt::clone() { + chillAST_Node *val = NULL; + if (getRetVal()) val = getRetVal()->clone(); + chillAST_ReturnStmt *RS = new chillAST_ReturnStmt(val); + RS->setParent(getParent()); + RS->isFromSourceFile = isFromSourceFile; + if (filename) RS->filename = strdup(filename); + return RS; +} + +chillAST_CallExpr::chillAST_CallExpr() { + children.push_back(NULL); +} + +chillAST_CallExpr::chillAST_CallExpr(chillAST_Node *c) : chillAST_CallExpr() { + setCallee(c); + grid = block = NULL; +} + +chillAST_Node *chillAST_CallExpr::clone() { + chillAST_CallExpr *CE = new chillAST_CallExpr(getCallee()->clone()); + for (int i = 1; i < getNumChildren(); i++) CE->addArg(getChild(i)->clone()); + CE->isFromSourceFile = isFromSourceFile; + if (filename) CE->filename = strdup(filename); + return CE; +} + + +chillAST_VarDecl::chillAST_VarDecl() { + vartype = underlyingtype = varname = arraypart = arraypointerpart = arraysetpart = NULL; + typedefinition = NULL; + init = NULL; + numdimensions = 0; + arraysizes = NULL; + parent = NULL; + metacomment = NULL; + vardef = NULL; + isStruct = false; + isAParameter = false; + byreference = false; + isABuiltin = false; + isRestrict = isDevice = isShared = false; + knownArraySizes = false; +}; + + +chillAST_VarDecl::chillAST_VarDecl(const char *t, const char *n, const char *a) { + vartype = strdup(t); + typedefinition = NULL; + + underlyingtype = parseUnderlyingType(vartype); + varname = strdup(n); + arraypointerpart = arraysetpart = NULL; + if (a) arraypart = strdup(a); + else arraypart = strdup(""); + splitarraypart(); + + init = NULL; + numdimensions = 0; + arraysizes = NULL; + uniquePtr = NULL; + + knownArraySizes = false; + for (int i = 0; i < strlen(a); i++) { + if (a[i] == '[') { + numdimensions++; + knownArraySizes = true; + } + if (!knownArraySizes && a[i] == '*') numdimensions++; + } + + vardef = NULL; + isStruct = false; + + //insideAStruct = false; + isAParameter = false; + byreference = false; + isABuiltin = false; + isRestrict = isDevice = isShared = false; // fprintf(stderr, "RDS = false\n"); +}; + + +chillAST_VarDecl::chillAST_VarDecl(chillAST_RecordDecl *astruct, const char *nam, const char *array) { + // define a variable whose type is a struct! + const char *type = astruct->getName(); + + vartype = strdup(type); + + // these always go together ?? + vardef = astruct;// pointer to the thing that says what is inside the struct + isStruct = true; // ?? wrong if it's a union ?? TODO + + underlyingtype = parseUnderlyingType(vartype); + varname = strdup(nam); + arraypart = strdup(array); + arraypointerpart = arraysetpart = NULL; + splitarraypart(); + + init = NULL; + numdimensions = 0; + arraysizes = NULL; + uniquePtr = NULL; + + knownArraySizes = false; + for (int i = 0; i < strlen(array); i++) { + if (array[i] == '[') { + numdimensions++; + knownArraySizes = true; + } + if (!knownArraySizes && array[i] == '*') numdimensions++; + } + + isAParameter = false; + fprintf(stderr, "%s is NOT a parameter\n", nam); + byreference = false; + isABuiltin = false; + isRestrict = isDevice = isShared = false; // fprintf(stderr, "RDS = false\n"); + typedefinition = NULL; +}; + + +chillAST_VarDecl::chillAST_VarDecl(chillAST_TypedefDecl *tdd, const char *n, const char *a) { + const char *type = tdd->getStructName(); + typedefinition = tdd; + vartype = strdup(type); + underlyingtype = parseUnderlyingType(vartype); + varname = strdup(n); + arraypart = strdup(a); + arraypointerpart = arraysetpart = NULL; + splitarraypart(); + + init = NULL; + numdimensions = 0; + arraysizes = NULL; + uniquePtr = NULL; + knownArraySizes = false; + for (int i = 0; i < strlen(a); i++) { + if (a[i] == '[') { + numdimensions++; + knownArraySizes = true; + } + if (!knownArraySizes && a[i] == '*') numdimensions++; + } + isStruct = tdd->isAStruct(); + vardef = NULL; + isAParameter = false; + byreference = false; + isABuiltin = false; + isRestrict = isDevice = isShared = false; +}; + + +chillAST_VarDecl::chillAST_VarDecl(const char *t, const char *n, const char *a, void *ptr) { + CHILL_DEBUG_PRINT("chillAST_VarDecl::chillAST_VarDecl( type %s, name %s, arraypart '%s' ) %p\n", t, n, a, this); + vartype = strdup(t); + typedefinition = NULL; + underlyingtype = parseUnderlyingType(vartype); + varname = strdup(n); + vardef = NULL; // not a struct + isStruct = false; + isAParameter = false; + if (a) arraypart = strdup(a); + else arraypart = strdup(""); // should catch this earlier + arraypointerpart = arraysetpart = NULL; + splitarraypart(); + init = NULL; + numdimensions = 0; + arraysizes = NULL; + uniquePtr = ptr; + knownArraySizes = false; + + for (int i = 0; i < strlen(a); i++) { + if (a[i] == '[') { + numdimensions++; + knownArraySizes = true; + } + if (!knownArraySizes && a[i] == '*') numdimensions++; // fails for a[4000 * 4] + } + // this is from ir_clang.cc ConvertVarDecl(), that got executed AFTER the vardecl was constructed. dumb + int numdim = 0; + //knownArraySizes = true; + //if (index(vartype, '*')) knownArraySizes = false; // float *a; for example + //if (index(arraypart, '*')) knownArraySizes = false; + + // note: vartype here, arraypart in next code.. is that right? + if (index(vartype, '*')) { + for (int i = 0; i < strlen(vartype); i++) if (vartype[i] == '*') numdim++; + numdimensions = numdim; + } + + if (index(arraypart, '[')) { // JUST [12][34][56] no asterisks + char *dupe = strdup(arraypart); + + int len = strlen(arraypart); + for (int i = 0; i < len; i++) if (dupe[i] == '[') numdim++; + + numdimensions = numdim; + int *as = (int *) malloc(sizeof(int *) * numdim); + if (!as) { + CHILL_ERROR("can't malloc array sizes in ConvertVarDecl()\n"); + exit(-1); + } + arraysizes = as; // 'as' changed later! + + + char *ptr = dupe; + while (ptr = index(ptr, '[')) { // this fails for float a[4000*4] + ptr++; + char *leak = strdup(ptr); + char *close = index(leak, ']'); + if (close) *close = '\0'; + + int l = strlen(leak); + bool justdigits = true; + bool justmath = true; + for (int i = 0; i < l; i++) { + char c = leak[i]; + if (!isdigit(c)) justdigits = false; + if (!(isdigit(c) || + isblank(c) || + ((c == '+') || (c == '*') || (c == '*') || (c == '*')) || // math + ((c == '(') || (c == ')'))) + ) { + justmath = false; + } + } + if (justdigits) { + int dim; + sscanf(ptr, "%d", &dim); + *as++ = dim; + } else { + if (justmath) fprintf(stderr, "JUST MATH\n"); + fprintf(stderr, "need to evaluate %s, faking with hardcoded 16000\n", leak); + *as++ = 16000; // temp TODO DFL + } + free(leak); + ptr = index(ptr, ']'); + } + free(dupe); + } + + byreference = false; + isABuiltin = false; + isRestrict = isDevice = isShared = false; + // currently this is bad, because a struct does not have a symbol table, so the + // members of a struct are passed up to the func or sourcefile. +}; + +chillAST_RecordDecl *chillAST_VarDecl::getStructDef() { + if (vardef) return vardef; + if (typedefinition) return typedefinition->getStructDef(); + return NULL; +} + + +chillAST_CompoundStmt::chillAST_CompoundStmt() { + parent = NULL; + symbolTable = new chillAST_SymbolTable; + typedefTable = new chillAST_TypedefTable; +}; + +void chillAST_CompoundStmt::replaceChild(chillAST_Node *old, chillAST_Node *newchild) { + vector dupe = children; + int numdupe = dupe.size(); + int any = 0; + + for (int i = 0; i < numdupe; i++) { + if (dupe[i] == old) { + children[i] = newchild; + newchild->setParent(this); + any = 1; + } + } + + if (!any) { + CHILL_ERROR("chillAST_CompoundStmt::replaceChild(), could not find old\n"); + exit(-1); + } +} + +chillAST_Node *chillAST_CompoundStmt::clone() { + chillAST_CompoundStmt *cs = new chillAST_CompoundStmt(); + for (int i = 0; i < children.size(); i++) cs->addChild(children[i]->clone()); + cs->setParent(getParent()); + cs->isFromSourceFile = isFromSourceFile; + if (filename) cs->filename = strdup(filename); + return cs; +} + +void chillAST_CompoundStmt::gatherArrayRefs(std::vector &refs, bool writtento) { + chillAST_Node::gatherArrayRefs(refs,false); +} + +void chillAST_CompoundStmt::gatherScalarRefs(std::vector &refs, bool writtento) { + chillAST_Node::gatherScalarRefs(refs,false); +} + +bool chillAST_CompoundStmt::findLoopIndexesToReplace(chillAST_SymbolTable *symtab, bool forcesync) { + + // see how many elements we currently have + int sofar = children.size(); + + // make big enough to add a sync after each statement. wasteful. TODO + // this prevents inserts happening at the forstmt::addSync() from causing a + // reallocation, which screwsup the loop below here + children.reserve(2 * sofar); + + bool force = false; + for (int i = 0; i < children.size(); i++) { // children.size() to see it gain each time + if (children.size() > sofar) + sofar = children.size(); + + bool thisforces = children[i]->findLoopIndexesToReplace(symtab, force); + force = force || thisforces; // once set, always + } + return false; + +/* + vector childrencopy; + for (int i=0; igetTypeString() ); + origtypes[i] = strdup( children[i]->getTypeString() ); + fprintf(stderr, "ORIGINAL compound child %d of type %s\n", i, children[i]->getTypeString() ); + } + + for (int i=0; igetTypeString(), force ); + force = force || childrencopy[i]->findLoopIndexesToReplace( symtab, force ); // once set, always + } + + fprintf(stderr, "\n"); + for (int i=0; igetTypeString() ); + } + + return false; +*/ +} + +chillAST_ParenExpr::chillAST_ParenExpr() { + children.push_back(NULL); +} + +chillAST_ParenExpr::chillAST_ParenExpr(chillAST_Node *sub):chillAST_ParenExpr() { + setSubExpr(sub); +} + +chillAST_Node *chillAST_ParenExpr::clone() { + chillAST_ParenExpr *PE = new chillAST_ParenExpr(getSubExpr()->clone()); + PE->setParent(getParent()); + PE->isFromSourceFile = isFromSourceFile; + if (filename) PE->filename = strdup(filename); + return PE; +} + +chillAST_Sizeof::chillAST_Sizeof(char *athing) { + thing = strdup(athing); // memory leak +} + +chillAST_Node *chillAST_Sizeof::clone() { + chillAST_Sizeof *SO = new chillAST_Sizeof(thing); + SO->setParent(getParent()); + SO->isFromSourceFile = isFromSourceFile; + if (filename) SO->filename = strdup(filename); + return SO; +} + +chillAST_IfStmt::chillAST_IfStmt() { + children.push_back(NULL); + children.push_back(NULL); + children.push_back(NULL); +} + +chillAST_IfStmt::chillAST_IfStmt(chillAST_Node *c, chillAST_Node *t, chillAST_Node *e) : chillAST_IfStmt() { + setCond(c); + setThen(t); + setElse(e); +} + +void chillAST_IfStmt::gatherArrayRefs(std::vector &refs, bool writtento) { + chillAST_Node::gatherArrayRefs(refs, false); +} + +void chillAST_IfStmt::gatherScalarRefs(std::vector &refs, bool writtento) { + chillAST_Node::gatherScalarRefs(refs, false); +} + +chillAST_Node *chillAST_IfStmt::clone() { + chillAST_Node *c, *t, *e; + c = t = e = NULL; + if (getCond()) c = getCond()->clone(); // has to be one, right? + if (getThen()) t = getThen()->clone(); + if (getElse()) e = getElse()->clone(); + + chillAST_IfStmt *IS = new chillAST_IfStmt(c, t, e); + IS->setParent(getParent()); + IS->isFromSourceFile = isFromSourceFile; + if (filename) IS->filename = strdup(filename); + return IS; +} + +bool chillAST_IfStmt::findLoopIndexesToReplace(chillAST_SymbolTable *symtab, bool forcesync) { + getThen()->findLoopIndexesToReplace(symtab); + getElse()->findLoopIndexesToReplace(symtab); + return false; // ?? +} + +chillAST_Node *minmaxTernary(const char * op, chillAST_Node *left, chillAST_Node *right) { + + chillAST_Node *lp1 = left->clone(); + chillAST_Node *rp1 = right->clone(); + chillAST_BinaryOperator *cond = new chillAST_BinaryOperator(lp1, op, rp1); + chillAST_Node *lp2 = left->clone(); + chillAST_Node *rp2 = right->clone(); + + return new chillAST_TernaryOperator("?", cond, lp2, rp2); +} + +// look for function declaration with a given name, in the tree with root "node" +void findFunctionDeclRecursive(chillAST_Node *node, const char *procname, vector &funcs) { + if (node->isFunctionDecl()) { + char *name = ((chillAST_FunctionDecl *) node)->functionName; // compare name with desired name + if (!strcmp(name, procname)) { + funcs.push_back((chillAST_FunctionDecl *) node); // this is it + return; + } + } + // this is where the children can be used effectively. + // we don't really care what kind of node we're at. We just check the node itself + // and then its children is needed. + int numc = node->getNumChildren(); + for (int i = 0; i < numc; i++) { + if (node->isSourceFile()) + if (node->getChild(i)->isFunctionDecl()) + chillAST_FunctionDecl *fd = (chillAST_FunctionDecl *) node->getChild(i); + findFunctionDeclRecursive(node->getChild(i), procname, funcs); + } + return; +} + +chillAST_SymbolTable *addSymbolToTable(chillAST_SymbolTable *st, chillAST_VarDecl *vd) // definition +{ + chillAST_SymbolTable *s = st; + if (!s) s = new chillAST_SymbolTable; + int tablesize = s->size(); + for (int i = 0; i < tablesize; i++) { + if ((*s)[i] == vd) { + return s; // already there + } + } + for (int i = 0; i < tablesize; i++) { + if (!strcmp((*s)[i]->varname, vd->varname)) { + return s; // already there + } + } + s->push_back(vd); // add it + return s; +} + +chillAST_TypedefTable *addTypedefToTable(chillAST_TypedefTable *tdt, chillAST_TypedefDecl *td) { + + chillAST_TypedefTable *t = tdt; + if (!t) t = new chillAST_TypedefTable; + + int tablesize = t->size(); + + for (int i = 0; i < tablesize; i++) { + if ((*t)[i] == td) return t; // already there + } + t->push_back(td); // add it + return t; +} + + +chillAST_NoOp::chillAST_NoOp() { +}; // so we have SOMETHING for NoOp in the cc file ??? + + +chillAST_Preprocessing::chillAST_Preprocessing() { + position = CHILLAST_PREPROCESSING_POSITIONUNKNOWN; + pptype = CHILLAST_PREPROCESSING_TYPEUNKNOWN; + blurb = strdup(""); // never use null. ignore the leak ?? +} + + +chillAST_Preprocessing::chillAST_Preprocessing(CHILLAST_PREPROCESSING_POSITION pos, + CHILLAST_PREPROCESSING_TYPE t, + char *text) { + position = pos; + pptype = t; + blurb = strdup(text); +} + diff --git a/src/chillASTs.cc b/src/chillASTs.cc deleted file mode 100644 index 1e670a7..0000000 --- a/src/chillASTs.cc +++ /dev/null @@ -1,2108 +0,0 @@ -#include -#include -#include -#include "chillAST.h" -#include "printer/dump.h" -#include "printer/cfamily.h" - -using namespace std; - -bool streq(const char *a, const char *b) { - return !strcmp(a, b); -} - -char *parseUnderlyingType(const char *sometype) { - int len = strlen(sometype); - CHILL_DEBUG_PRINT("parseUnderlyingType( %s )\n", sometype); - char *underlying = strdup(sometype); - char *p; - - p = &underlying[len - 1]; - - while (p > underlying) - if (*p == ' ' || *p == '*') - --p; - else if (*p == ']') { - while (*p != '[') --p; - --p; - } - else break; - - *(p + 1) = '\0'; - - return underlying; -} - -char *splitVariableName(char *name) { - char *cdot = strstr(name, "."); - char *carrow = strstr(name, "->"); // initial 'c' for const - can't change those - - int pos = INT16_MAX, pend; - - if (cdot) pend = pos = (int) (cdot - name); - if (carrow) { - pos = min(pos, (int) (carrow - name)); - pend = pos + 1; - } - - if (pos == INT16_MAX) - return NULL; - - name[pos] = '\0'; - return &name[pend + 1]; - -} - -chillAST_VarDecl *symbolTableFindName(chillAST_SymbolTable *table, const char *name) { - if (!table) return NULL; - int numvars = table->size(); - for (int i = 0; i < numvars; i++) { - chillAST_VarDecl *vd = (*table)[i]; - if (vd->nameis(name)) return vd; - } - return NULL; -} - -chillAST_TypedefDecl *typedefTableFindName(chillAST_TypedefTable *table, const char *name) { - if (!table) return NULL; - int numvars = table->size(); - for (int i = 0; i < numvars; i++) { - chillAST_TypedefDecl *td = (*table)[i]; - if (td->nameis(name)) return td; - } - return NULL; -} - -chillAST_VarDecl *variableDeclFindSubpart(chillAST_VarDecl *decl, const char *name) { - char *varname = strdup(name), *subpart; - - subpart = splitVariableName(varname); - - if (decl->isAStruct()) { - CHILL_DEBUG_PRINT("Finding %s in a struct of type %s\n", varname, decl->getTypeString()); - if (decl->isVarDecl()) { - chillAST_RecordDecl *rd = decl->getStructDef(); - if (rd) { - chillAST_VarDecl *sp = rd->findSubpart(varname); - if (sp) CHILL_DEBUG_PRINT("found a struct member named %s\n", varname); - else - CHILL_DEBUG_PRINT("DIDN'T FIND a struct member named %s\n", varname); - if (!subpart) - return sp; - return variableDeclFindSubpart(sp, subpart); // return the subpart?? - } else { - CHILL_ERROR("no recordDecl\n"); - exit(-1); - } - } else { - CHILL_ERROR("NOT a VarDecl???\n"); // impossible - } - } else { - CHILL_DEBUG_PRINT("false alarm. %s is a variable, but doesn't have subparts\n", varname); - return NULL; - } -} - -chillAST_VarDecl *symbolTableFindVariableNamed(chillAST_SymbolTable *table, const char *name) { - if (!table) return NULL; - - char *varname = strdup(name), *subpart; - - subpart = splitVariableName(varname); - - chillAST_VarDecl *vd = symbolTableFindName(table, varname); - - if (!subpart) - return vd; - return variableDeclFindSubpart(vd, subpart); -} - -char *ulhack(char *brackets) { - CHILL_DEBUG_PRINT("ulhack( \"%s\" -> \n", brackets); - int len = strlen(brackets); - for (int i = 0; i < len - 2; i++) { - if (isdigit(brackets[i])) { - if (brackets[i + 1] == 'U' && brackets[i + 2] == 'L') { // remove - for (int j = i + 3; j < len; j++) brackets[j - 2] = brackets[j]; - len -= 2; - brackets[len] = '\0'; - } - } - } - return brackets; -} - -char *restricthack(char *typeinfo) { - CHILL_DEBUG_PRINT("restricthack( \"%s\" -> \n", typeinfo); - std::string r("__restrict__"); - std::string t(typeinfo); - size_t index = t.find(r); - - if (index == std::string::npos) return typeinfo; - - char *c = &(typeinfo[index]); - char *after = c + 12; - if (*after == ' ') after++; - - while (*after != '\0') *c++ = *after++; - *c = '\0'; - - return typeinfo; - -} - -// TODO DOC -char *parseArrayParts(char *sometype) { - int len = strlen(sometype); - char *arraypart = (char *) calloc(1 + strlen(sometype), sizeof(char));// leak - - int c = 0; - for (int i = 0; i < strlen(sometype);) { - if (sometype[i] == '*') arraypart[c++] = '*'; - if (sometype[i] == '[') { - while (sometype[i] != ']') { - arraypart[c++] = sometype[i++]; - } - arraypart[c++] = ']'; - } - i += 1; - } - ulhack(arraypart); - restricthack(arraypart); - - CHILL_DEBUG_PRINT("parseArrayParts( %s ) => %s\n", sometype, arraypart); - return arraypart; -} - - -//! return the bracketed part of a type, int *buh[32] to int -char *splitTypeInfo(char *underlyingtype) { - char *ap = ulhack(parseArrayParts(underlyingtype)); - - strcpy(underlyingtype, parseUnderlyingType(underlyingtype)); - return ap; // leak unless caller frees this -} - - -bool isRestrict(const char *sometype) { // does not modify sometype - string r("__restrict__"); - string t(sometype); - return (std::string::npos != t.find(r)); -} - -void chillindent(int howfar, FILE *fp) { for (int i = 0; i < howfar; i++) fprintf(fp, " "); } - -chillAST_SourceFile::chillAST_SourceFile(const char *filename) { - if (filename) SourceFileName = strdup(filename); - else SourceFileName = strdup("No Source File"); - symbolTable = new chillAST_SymbolTable(); - typedefTable = new chillAST_TypedefTable(); - FileToWrite = NULL; - frontend = strdup("unknown"); -}; - -void chillAST_SourceFile::printToFile(char *filename) { - char fn[1024]; - - if (NULL == filename) { // build up a filename using original name and frontend if known - if (FileToWrite) { - strcpy(fn, FileToWrite); - } else { - // input name with name of frontend compiler prepended - if (frontend) sprintf(fn, "%s_%s\0", frontend, SourceFileName); - else sprintf(fn, "UNKNOWNFRONTEND_%s\0", SourceFileName); // should never happen - } - } else strcpy(fn, filename); - - std::ofstream fo(fn); - if (fo.fail()) { - CHILL_ERROR("can't open file '%s' for writing\n", fn); - exit(-1); - } - chill::printer::CFamily cp; - cp.print("",this,fo); - -} - -chillAST_MacroDefinition *chillAST_SourceFile::findMacro(const char *name) { - int numMacros = macrodefinitions.size(); - for (int i = 0; i < numMacros; i++) { - if (!strcmp(macrodefinitions[i]->macroName, name)) return macrodefinitions[i]; - } - return NULL; // not found -} - - -chillAST_FunctionDecl *chillAST_SourceFile::findFunction(const char *name) { - int numFuncs = functions.size(); - for (int i = 0; i < numFuncs; i++) { - if (!strcmp(functions[i]->functionName, name)) return functions[i]; - } - return NULL; -} - - -chillAST_Node *chillAST_SourceFile::findCall(const char *name) { - chillAST_MacroDefinition *macro = findMacro(name); - if (macro) return (chillAST_Node *) macro; - chillAST_FunctionDecl *func = findFunction(name); - return func; -} - -chillAST_TypedefDecl::chillAST_TypedefDecl() { - underlyingtype = newtype = arraypart = NULL; - parent = NULL; - metacomment = NULL; - isStruct = isUnion = false; - structname = NULL; - rd = NULL; - isFromSourceFile = true; // default - filename = NULL; -}; - - -chillAST_TypedefDecl::chillAST_TypedefDecl(char *t, const char *nt) { - underlyingtype = strdup(t); - newtype = strdup(nt); - arraypart = NULL; - metacomment = NULL; - isStruct = isUnion = false; - structname = NULL; - rd = NULL; - isFromSourceFile = true; // default - filename = NULL; -}; - - -chillAST_TypedefDecl::chillAST_TypedefDecl(char *t, const char *a, char *p) { - underlyingtype = strdup(t); - newtype = strdup(a); - - arraypart = strdup(p); - // splitarraypart(); // TODO - - metacomment = NULL; - isStruct = isUnion = false; - structname = NULL; - rd = NULL; - isFromSourceFile = true; // default - filename = NULL; -}; - -chillAST_VarDecl *chillAST_TypedefDecl::findSubpart(const char *name) { - if (rd) { // we have a record decl look there - chillAST_VarDecl *sub = rd->findSubpart(name); - return sub; - } - - // can this ever happen now ??? - int nsub = subparts.size(); - for (int i = 0; i < nsub; i++) { - if (!strcmp(name, subparts[i]->varname)) return subparts[i]; - } - CHILL_ERROR("subpart not found\n"); - return NULL; -} - - -chillAST_RecordDecl *chillAST_TypedefDecl::getStructDef() { - if (rd) return rd; - return NULL; -} - -chillAST_RecordDecl::chillAST_RecordDecl(const char *nam, const char *orig) { - if (nam) name = strdup(nam); - else name = strdup("unknown"); // ?? - - originalname = NULL; - symbolTable = new chillAST_SymbolTable(); - if (orig) originalname = strdup(orig); - - isStruct = isUnion = false; - isFromSourceFile = true; // default - filename = NULL; -} - - -chillAST_VarDecl *chillAST_RecordDecl::findSubpart(const char *nam) { - int nsub = subparts.size(); - for (int i = 0; i < nsub; i++) { - if (!strcmp(nam, subparts[i]->varname)) return subparts[i]; - } - CHILL_DEBUG_PRINT("chillAST_RecordDecl::findSubpart() couldn't find member NAMED %s in ", nam); - print(); - return NULL; -} - - -chillAST_VarDecl *chillAST_RecordDecl::findSubpartByType(const char *typ) { - int nsub = subparts.size(); - for (int i = 0; i < nsub; i++) { - if (!strcmp(typ, subparts[i]->vartype)) return subparts[i]; - } - return NULL; -} - -chillAST_SymbolTable *chillAST_RecordDecl::addVariableToSymbolTable(chillAST_VarDecl *vd) { - // for now, just bail. or do we want the struct to have an actual symbol table? - return NULL; // damn, I hope nothing uses this! -} - -chillAST_FunctionDecl::chillAST_FunctionDecl(const char *rt, const char *fname, void *unique) { - CHILL_DEBUG_PRINT("chillAST_FunctionDecl::chillAST_FunctionDecl with unique %p\n", unique); - if (fname) - functionName = strdup(fname); - else - functionName = strdup("YouScrewedUp"); - forwarddecl = externfunc = builtin = false; - parameters = new chillAST_SymbolTable(); - this->setFunctionCPU(); - returnType = strdup(rt); - this->setFunctionCPU(); - children.push_back(new chillAST_CompoundStmt()); - uniquePtr = unique; // a quick way to check equivalence. DO NOT ACCESS THROUGH THIS -}; - -void chillAST_FunctionDecl::gatherVarDecls(vector &decls) { - for (int i = 0; i < getParameters()->size(); i++) (*getParameters())[i]->gatherVarDecls(decls); - for (int i = 0; i < children.size(); i++) children[i]->gatherVarDecls(decls); -} - - -void chillAST_FunctionDecl::gatherScalarVarDecls(vector &decls) { - for (int i = 0; i < getParameters()->size(); i++) (*getSymbolTable())[i]->gatherScalarVarDecls(decls); - for (int i = 0; i < children.size(); i++) children[i]->gatherScalarVarDecls(decls); -} - - -void chillAST_FunctionDecl::gatherArrayVarDecls(vector &decls) { - for (int i = 0; i < getParameters()->size(); i++) (*getSymbolTable())[i]->gatherArrayVarDecls(decls); - for (int i = 0; i < children.size(); i++) children[i]->gatherArrayVarDecls(decls); -} - - -chillAST_VarDecl *chillAST_FunctionDecl::findArrayDecl(const char *name) { - chillAST_VarDecl *p = getVariableDeclaration(name); - if (p && p->isArray()) return p; - chillAST_VarDecl *v = getBody()->getVariableDeclaration(name); - if (v && v->isArray()) return v; - // declared variables that may not be in symbol table but probably should be - vector decls; - gatherArrayVarDecls(decls); - for (int i = 0; i < decls.size(); i++) { - chillAST_VarDecl *vd = decls[i]; - if (0 == strcmp(vd->varname, name) && vd->isArray()) return vd; - } - return NULL; -} - -void chillAST_FunctionDecl::cleanUpVarDecls() { - vector used; - vector defined; - vector deletethese; - - gatherVarUsage(used); - gatherVarDecls(defined); - - for (int j = 0; j < defined.size(); j++) { - bool definedandused = false; - for (int i = 0; i < used.size(); i++) { - if (used[i] == defined[j]) { - definedandused = true; - break; - } - } - - if (!definedandused) { - if (!defined[j]->isParmVarDecl()) { - deletethese.push_back(defined[j]); - } - } - } - - for (int i = 0; i < deletethese.size(); i++) { - chillAST_Node *par = deletethese[i]->getParent(); - par->removeChild(par->findChild(deletethese[i])); - } - - // now check for vars used but not defined? - for (int j = 0; j < used.size(); j++) { - bool definedandused = false; - for (int i = 0; i < defined.size(); i++) { - if (used[j] == defined[i]) { - definedandused = true; - break; - } - } - if (!definedandused) { - insertChild(0, used[j]); - } - } - -} - - -bool chillAST_FunctionDecl::findLoopIndexesToReplace(chillAST_SymbolTable *symtab, bool forcesync) { - if (getBody()) getBody()->findLoopIndexesToReplace(symtab, false); - return false; -} - -chillAST_MacroDefinition::chillAST_MacroDefinition(const char *mname = NULL, const char *rhs = NULL) { - if (mname) macroName = strdup(mname); else macroName = strdup("UNDEFINEDMACRO"); - metacomment = NULL; - parameters = new chillAST_SymbolTable(); - isFromSourceFile = true; // default - filename = NULL; -}; - - -chillAST_Node *chillAST_MacroDefinition::clone() { - CHILL_ERROR("cloning a macro makes no sense\n"); - return this; - chillAST_MacroDefinition *clo = new chillAST_MacroDefinition(macroName); - clo->setParent(parent); - for (int i = 0; i < parameters->size(); i++) clo->addVariableToScope((*parameters)[i]); - clo->setBody(body->clone()); - return clo; -} - - -void chillAST_MacroDefinition::setBody(chillAST_Node *bod) { - bod->setParent(this); // well, ... -} - -chillAST_ForStmt::chillAST_ForStmt() { - children.push_back(NULL); // init - children.push_back(NULL); // cond - children.push_back(NULL); // incr - children.push_back(new chillAST_CompoundStmt()); // Body - - conditionoperator = IR_COND_UNKNOWN; - symbolTable = new chillAST_SymbolTable(); -} - - -chillAST_ForStmt::chillAST_ForStmt(chillAST_Node *ini, chillAST_Node *con, chillAST_Node *inc, chillAST_Node *bod) - : chillAST_ForStmt() { - setInit(ini); - setCond(con); - setInc(inc); - setBody(bod); - - if (!con->isBinaryOperator()) { - CHILL_ERROR("ForStmt conditional is of type %s. Expecting a BinaryOperator\n", con->getTypeString()); - exit(-1); - } - chillAST_BinaryOperator *bo = (chillAST_BinaryOperator *) con; - char *condstring = bo->op; - if (!strcmp(condstring, "<")) conditionoperator = IR_COND_LT; - else if (!strcmp(condstring, "<=")) conditionoperator = IR_COND_LE; - else if (!strcmp(condstring, ">")) conditionoperator = IR_COND_GT; - else if (!strcmp(condstring, ">=")) conditionoperator = IR_COND_GE; - else { - CHILL_ERROR("ForStmt, illegal/unhandled end condition \"%s\"\n", condstring); - CHILL_ERROR("currently can only handle <, >, <=, >=\n"); - exit(1); - } -} - -chillAST_Node *chillAST_ForStmt::clone() { - chillAST_ForStmt *fs = new chillAST_ForStmt(getInit()->clone(), getCond()->clone(), getInc()->clone(), - getBody()->clone()); - fs->isFromSourceFile = isFromSourceFile; - if (filename) fs->filename = strdup(filename); - fs->setParent(getParent()); - return fs; -} - -void chillAST_ForStmt::addSyncs() { - if (!parent) { - CHILL_ERROR("uhoh, chillAST_ForStmt::addSyncs() ForStmt has no parent!\n"); - - return; // exit? - } - - if (parent->isCompoundStmt()) { - vector *chillin = parent->getChildren(); - int numc = chillin->size(); - for (int i = 0; i < numc; i++) { - if (this == parent->getChild(i)) { - chillAST_CudaSyncthreads *ST = new chillAST_CudaSyncthreads(); - parent->insertChild(i + 1, ST); // corrupts something ... - } - } - chillin = parent->getChildren(); - int nowc = chillin->size(); - } else { - fprintf(stderr, "chillAST_ForStmt::addSyncs() unhandled parent type %s\n", parent->getTypeString()); - exit(-1); - } -} - - -void chillAST_ForStmt::removeSyncComment() { - if (metacomment && strstr(metacomment, "~cuda~") && strstr(metacomment, "preferredIdx: ")) { - char *ptr = strlen("preferredIdx: ") + strstr(metacomment, "preferredIdx: "); - *ptr = '\0'; - } -} - - -bool chillAST_ForStmt::findLoopIndexesToReplace(chillAST_SymbolTable *symtab, bool forcesync) { - CHILL_DEBUG_PRINT("\nchillAST_ForStmt::findLoopIndexesToReplace( force = %d )\n", forcesync); - bool force = forcesync; - bool didasync = false; - if (forcesync) { - addSyncs(); - didasync = true; - } - if (metacomment && strstr(metacomment, "~cuda~") && strstr(metacomment, "preferredIdx: ")) { - char *copy = strdup(metacomment); - char *ptr = strstr(copy, "preferredIdx: "); - char *vname = ptr + strlen("preferredIdx: "); - char *space = strstr(vname, " "); // TODO index() - if (space) - force = true; - if ((!didasync) && force) { - addSyncs(); - removeSyncComment(); - didasync = true; - } - - if (space) *space = '\0'; // if this is multiple words, grab the first one - - vector decls; - getInit()->gatherVarLHSUsage(decls); - //cond->gatherVarUsage( decls ); - //incr->gatherVarUsage( decls ); - - if (1 != decls.size()) { - CHILL_ERROR("uhoh, preferred index in for statement, but multiple variables used\n"); - print(0, stderr); - fprintf(stderr, "\nvariables are:\n"); - for (int i = 0; i < decls.size(); i++) { - decls[i]->print(0, stderr); - fprintf(stderr, "\n"); - } - exit(0); - } - chillAST_VarDecl *olddecl = decls[0]; - - // RIGHT NOW, change all the references that this loop wants swapped out - // find vardecl for named preferred index. it has to already exist - chillAST_VarDecl *newguy = findVariableDecleration(vname); // recursive - if (!newguy) - CHILL_ERROR("there was no variable named %s anywhere I could find\n", vname); - - // wrong - this only looks at variables defined in the forstmt, not - // in parents of the forstmt - if (!newguy) { - CHILL_DEBUG_PRINT("chillAST_ForStmt::findLoopIndexesToReplace() there is no defined variable %s\n", vname); - - // make one ?? seems like this should never happen - newguy = new chillAST_VarDecl(olddecl->vartype, vname, ""/*?*/, NULL); - // insert actual declaration in code location? how? - - // find parent of the ForStmt? - // find parent^n of the ForStmt that is not a Forstmt? - // find parent^n of the Forstmt that is a FunctionDecl? - chillAST_Node *contain = findContainingNonLoop(); - if (contain == NULL) { - CHILL_ERROR("nothing but loops all the way up?\n"); - exit(0); - } - contain->print(0, stderr); - contain->insertChild(0, newguy); // TODO ugly order - contain->addVariableToScope(newguy); // adds to first enclosing symbolTable - - if (!symbolTableFindName(contain->getSymbolTable(), vname)) { - CHILL_ERROR("container doesn't have a var names %s afterwards???\n", vname); - exit(-1); - } - } - // swap out old for new in init, cond, incr, body - if (newguy) - replaceVarDecls(olddecl, newguy); - metacomment = NULL; // memleak - } - // check for more loops. We may have already swapped variables out in body (right above here) - getBody()->findLoopIndexesToReplace(symtab, false); - return force; -} - -void chillAST_ForStmt::gatherLoopIndeces(std::vector &indeces) { - vector decls; - getInit()->gatherVarLHSUsage(decls); - getCond()->gatherVarLHSUsage(decls); - getInc()->gatherVarLHSUsage(decls); - // note: NOT GOING INTO BODY OF THE LOOP - - int numdecls = decls.size(); - for (int i = 0; i < decls.size(); i++) - indeces.push_back(decls[i]); - - // Don't forget to keep heading upwards! - if (parent) - parent->gatherLoopIndeces(indeces); -} - - -void chillAST_ForStmt::gatherLoopVars(std::vector &loopvars) { - vector decls; - getInit()->gatherVarLHSUsage(decls); - getCond()->gatherVarLHSUsage(decls); - getInc()->gatherVarLHSUsage(decls); - // note: NOT GOING INTO BODY OF THE LOOP - for (int i = 0; i < decls.size(); i++) loopvars.push_back(strdup(decls[i]->varname)); -} - - -void chillAST_ForStmt::loseLoopWithLoopVar(char *var) { - - //fprintf(stderr, "\nchillAST_ForStmt::loseLoopWithLoopVar( %s )\n", var ); - - // now recurse (could do first, I suppose) - // if you DON'T do this first, you may have already replaced yourself with this loop body - // the body will no longer have this forstmt as parent, it will have the forstmt's parent as its parent - //fprintf(stderr, "forstmt 0x%x, recursing loseLoop to body 0x%x of type %s with parent 0x%x of type %s\n", this, body, body->getTypeString(), body->parent, body->parent->getTypeString()); - getBody()->loseLoopWithLoopVar(var); - - - - - // if *I* am a loop to be replaced, tell my parent to replace me with my loop body - - std::vector loopvars; - gatherLoopVars(loopvars); - - if (loopvars.size() != 1) { - fprintf(stderr, "uhoh, loop has more than a single loop var and trying to loseLoopWithLoopVar()\n"); - print(0, stderr); - fprintf(stderr, "\nvariables are:\n"); - for (int i = 0; i < loopvars.size(); i++) { - fprintf(stderr, "%s\n", loopvars[i].c_str()); - } - - exit(-1); - } - - //fprintf(stderr, "my loop var %s, looking for %s\n", loopvars[0].c_str(), var ); - if (!strcmp(var, loopvars[0].c_str())) { - //fprintf(stderr, "OK, trying to lose myself! for ("); - //init->print(0, stderr); - //fprintf(stderr, "; "); - //cond->print(0, stderr); - //fprintf(stderr, "; "); - //incr->print(0, stderr); - //fprintf(stderr, ")\n" ); - - if (!parent) { - fprintf(stderr, "chillAST_ForStmt::loseLoopWithLoopVar() I have no parent!\n"); - exit(-1); - } - - vector decls; - getInit()->gatherVarLHSUsage(decls); // this can fail if init is outside the loop - getCond()->gatherVarLHSUsage(decls); - getInc()->gatherVarLHSUsage(decls); - if (decls.size() > 1) { - fprintf(stderr, "chill_ast.cc multiple loop variables confuses me\n"); - exit(-1); - } - chillAST_Node *newstmt = getBody(); - - // ACTUALLY, if I am being replaced, and my loop conditional is a min (Ternary), then wrap my loop body in an if statement - if (getCond()->isBinaryOperator()) { // what else could it be? - chillAST_BinaryOperator *BO = (chillAST_BinaryOperator *) getCond(); - if (BO->getRHS()->isTernaryOperator()) { - - chillAST_TernaryOperator *TO = (chillAST_TernaryOperator *) BO->getRHS(); - chillAST_BinaryOperator *C = (chillAST_BinaryOperator *) TO->getCond(); - - //fprintf(stderr, "loop condition RHS is ternary\nCondition RHS"); - C->print(); - chillAST_Node *l = C->getLHS(); - if (l->isParenExpr()) l = ((chillAST_ParenExpr *) l)->getSubExpr(); - chillAST_Node *r = C->getRHS(); - if (r->isParenExpr()) r = ((chillAST_ParenExpr *) r)->getSubExpr(); - - //fprintf(stderr, "lhs is %s rhs is %s\n", l->getTypeString(), r->getTypeString()); - - chillAST_Node *ifcondrhs = NULL; - if (!(l->isConstant())) ifcondrhs = l; - else if (!(r->isConstant())) ifcondrhs = r; - else { - // should never happen. 2 constants. infinite loop - fprintf(stderr, "chill_ast.cc INIFNITE LOOP?\n"); - this->print(0, stderr); - fprintf(stderr, "\n\n"); - exit(-1); - } - - // wrap the loop body in an if - chillAST_DeclRefExpr *DRE = new chillAST_DeclRefExpr(decls[0]); - chillAST_BinaryOperator *ifcond = new chillAST_BinaryOperator(DRE, "<=", ifcondrhs); - chillAST_IfStmt *ifstmt = new chillAST_IfStmt(ifcond, getBody(), NULL); - - newstmt = ifstmt; - } - } - - //fprintf(stderr, "forstmt 0x%x has parent 0x%x of type %s\n", this, parent, parent->getTypeString()); - //fprintf(stderr, "forstmt will be replaced by\n"); - //newstmt->print(0,stderr); fprintf(stderr, "\n\n"); - - parent->replaceChild(this, newstmt); - } - - -} - -chillAST_BinaryOperator::chillAST_BinaryOperator() { - children.push_back(NULL); - children.push_back(NULL); -} - -chillAST_BinaryOperator::chillAST_BinaryOperator(chillAST_Node *l, const char *oper, chillAST_Node *r) - : chillAST_BinaryOperator() { - CHILL_DEBUG_PRINT("( l %s r )\n", oper); - - setLHS(l); - setRHS(r); - - if (oper) op = strdup(oper); - - // if this writes to lhs and lhs type has an 'imwrittento' concept, set that up - if (isAssignmentOp()) { - if (l && l->isArraySubscriptExpr()) { - ((chillAST_ArraySubscriptExpr *) l)->imwrittento = true; - } - } - if (isAugmentedAssignmentOp()) { // += etc - if (l && l->isArraySubscriptExpr()) { - ((chillAST_ArraySubscriptExpr *) l)->imreadfrom = true; // note will ALSO have imwrittento true - } - } - - isFromSourceFile = true; // default - filename = NULL; -} - - -int chillAST_BinaryOperator::evalAsInt() { - // very limited. allow +-*/ and integer literals ... - if (isAssignmentOp()) return getRHS()->evalAsInt(); // ?? ignores/loses lhs info - - if (!strcmp("+", op)) { - //fprintf(stderr, "chillAST_BinaryOperator::evalAsInt() %d + %d\n", lhs->evalAsInt(), rhs->evalAsInt()); - return getLHS()->evalAsInt() + getRHS()->evalAsInt(); - } - if (!strcmp("-", op)) return getLHS()->evalAsInt() - getRHS()->evalAsInt(); - if (!strcmp("*", op)) return getLHS()->evalAsInt() * getRHS()->evalAsInt(); - if (!strcmp("/", op)) return getLHS()->evalAsInt() / getRHS()->evalAsInt(); - - fprintf(stderr, "chillAST_BinaryOperator::evalAsInt() unhandled op '%s'\n", op); - exit(-1); -} - -chillAST_IntegerLiteral *chillAST_BinaryOperator::evalAsIntegerLiteral() { - return new chillAST_IntegerLiteral(evalAsInt()); // ?? -} - -class chillAST_Node *chillAST_BinaryOperator::constantFold() { - chillAST_Node::constantFold(); - - chillAST_Node *returnval = this; - - if (getLHS()->isConstant() && getRHS()->isConstant()) { - if (!strcmp(op, "+") || !strcmp(op, "-") || !strcmp(op, "*")) { - if (getLHS()->isIntegerLiteral() && getRHS()->isIntegerLiteral()) { - chillAST_IntegerLiteral *l = (chillAST_IntegerLiteral *) getLHS(); - chillAST_IntegerLiteral *r = (chillAST_IntegerLiteral *) getRHS(); - chillAST_IntegerLiteral *I; - - if (!strcmp(op, "+")) I = new chillAST_IntegerLiteral(l->value + r->value); - if (!strcmp(op, "-")) I = new chillAST_IntegerLiteral(l->value - r->value); - if (!strcmp(op, "*")) I = new chillAST_IntegerLiteral(l->value * r->value); - - returnval = I; - } else { - - // usually don't want to do this for floats or doubles - // could probably check for special cases like 0.0/30.0 or X/X or X/1.0 - double lval, rval; - int prec = 1; - if (getLHS()->isIntegerLiteral()) - lval = ((chillAST_IntegerLiteral *)getLHS())->value; - else { - lval = ((chillAST_FloatingLiteral *)getLHS())->value; - prec = max(prec, ((chillAST_FloatingLiteral *)getLHS())->getPrecision()); - } - - if (getRHS()->isIntegerLiteral()) - rval = ((chillAST_IntegerLiteral *)getRHS())->value; - else { - rval = ((chillAST_FloatingLiteral *) getRHS())->value; - prec = max(prec, ((chillAST_FloatingLiteral *) getRHS())->getPrecision()); - } - - chillAST_FloatingLiteral *F; - // NOT SAFE - // if (streq(op, "+")) F = new chillAST_FloatingLiteral(lval + rval, parent); - // if (streq(op, "-")) F = new chillAST_FloatingLiteral(lval - rval, parent); - if (streq(op, "*")) F = new chillAST_FloatingLiteral(lval * rval, prec, NULL); - - returnval = F; - - } - } - //else fprintf(stderr, "can't fold op '%s' yet\n", op); - } - - //fprintf(stderr, "returning "); returnval->print(0,stderr); fprintf(stderr, "\n"); - return returnval; -} - - -class chillAST_Node *chillAST_BinaryOperator::clone() { - //fprintf(stderr, "chillAST_BinaryOperator::clone() "); print(); printf("\n"); fflush(stdout); - - chillAST_Node *l = getLHS()->clone(); - chillAST_Node *r = getRHS()->clone(); - chillAST_BinaryOperator *bo = new chillAST_BinaryOperator(l, op, r); - l->setParent(bo); - r->setParent(bo); - bo->isFromSourceFile = isFromSourceFile; - if (filename) bo->filename = strdup(filename); - return bo; -} - -void chillAST_BinaryOperator::gatherArrayRefs(std::vector &refs, bool w) { - getLHS()->gatherArrayRefs(refs, isAssignmentOp()); - getRHS()->gatherArrayRefs(refs, 0); -} - -void chillAST_BinaryOperator::gatherScalarRefs(std::vector &refs, bool writtento) { - getLHS()->gatherScalarRefs(refs, isAssignmentOp()); - getRHS()->gatherScalarRefs(refs, 0); -} - -void chillAST_BinaryOperator::gatherVarLHSUsage(vector &decls) { - getLHS()->gatherVarUsage(decls); -} - -chillAST_TernaryOperator::chillAST_TernaryOperator() { - op = strdup("?"); - children.push_back(NULL); - children.push_back(NULL); - children.push_back(NULL); -} - -chillAST_TernaryOperator::chillAST_TernaryOperator(const char *oper, chillAST_Node *c, chillAST_Node *l, - chillAST_Node *r) : chillAST_TernaryOperator() { - if (op) op = strdup(oper); - setCond(c); - setLHS(l); - setRHS(r); -} - -void chillAST_TernaryOperator::gatherVarLHSUsage(vector &decls) { - // this makes no sense for ternary ?? -} - -class chillAST_Node *chillAST_TernaryOperator::constantFold() { - chillAST_Node::constantFold(); - - chillAST_Node *returnval = this; - - if (getCond()->isConstant()) { - // TODO - } - - return returnval; -} - -class chillAST_Node *chillAST_TernaryOperator::clone() { - chillAST_Node *c = getCond()->clone(); - chillAST_Node *l = getLHS()->clone(); - chillAST_Node *r = getRHS()->clone(); - chillAST_TernaryOperator *to = new chillAST_TernaryOperator(op, c, l, r); - to->isFromSourceFile = isFromSourceFile; - filename = NULL; - return to; -} - -chillAST_ArraySubscriptExpr::chillAST_ArraySubscriptExpr() { - children.push_back(NULL); // Base - children.push_back(NULL); // Index - basedecl = NULL; -} - -chillAST_ArraySubscriptExpr::chillAST_ArraySubscriptExpr(chillAST_Node *bas, chillAST_Node *indx, bool writtento, - void *unique):chillAST_ArraySubscriptExpr() { - imwrittento = writtento; // ?? - imreadfrom = false; // ?? - if (bas) { - if (bas->isImplicitCastExpr()) setBase(((chillAST_ImplicitCastExpr *) bas)->getSubExpr()); // probably wrong - else setBase(bas); - basedecl = multibase(); - } - if (indx) { - if (indx->isImplicitCastExpr()) setIndex(((chillAST_ImplicitCastExpr *) indx)->getSubExpr()); // probably wrong - else setIndex(indx); - } - uniquePtr = unique; -} - -chillAST_ArraySubscriptExpr::chillAST_ArraySubscriptExpr(chillAST_VarDecl *v, std::vector indeces):chillAST_ArraySubscriptExpr() { - int numindeces = indeces.size(); - for (int i = 0; i < numindeces; i++) { - fprintf(stderr, "ASE index %d ", i); - indeces[i]->print(0, stderr); - fprintf(stderr, "\n"); - } - chillAST_DeclRefExpr *DRE = new chillAST_DeclRefExpr(v->vartype, v->varname, v); - basedecl = v; // ?? - - chillAST_ArraySubscriptExpr *rent = this; // parent for subnodes - - // these are on the top level ASE that we're creating here - setBase(DRE); - setIndex(indeces[numindeces - 1]); - - for (int i = numindeces - 2; i >= 0; i--) { - - chillAST_ArraySubscriptExpr *ASE = new chillAST_ArraySubscriptExpr(DRE, indeces[i], rent, 0); - rent->setBase(ASE); - } - - imwrittento = false; - imreadfrom = false; - isFromSourceFile = true; - filename = NULL; -} - -void chillAST_ArraySubscriptExpr::gatherIndeces(std::vector &ind) { - if (getBase()->isArraySubscriptExpr()) ((chillAST_ArraySubscriptExpr*)getBase())->gatherIndeces(ind); - ind.push_back(getIndex()); -} - -chillAST_VarDecl *chillAST_ArraySubscriptExpr::multibase() { - return getBase()->multibase(); -} - - -chillAST_Node *chillAST_ArraySubscriptExpr::getIndex(int dim) { - CHILL_DEBUG_PRINT("chillAST_ArraySubscriptExpr::getIndex( %d )\n", dim); - chillAST_Node *b = getBase(); - int depth = 0; - std::vector ind; - chillAST_Node *curindex = getIndex(); - for (;;) { - if (b->getType() == CHILLAST_NODE_IMPLICITCASTEXPR) - b = ((chillAST_ImplicitCastExpr *) b)->getSubExpr(); - else if (b->getType() == CHILLAST_NODE_ARRAYSUBSCRIPTEXPR) { - ind.push_back(curindex); - curindex = ((chillAST_ArraySubscriptExpr *) b)->getIndex(); - b = ((chillAST_ArraySubscriptExpr *) b)->getBase(); - depth++; - } else { - ind.push_back(curindex); - break; - } - } - return ind[depth - dim]; -} - -class chillAST_Node *chillAST_ArraySubscriptExpr::clone() { - chillAST_Node *b = getBase()->clone(); - chillAST_Node *i = getIndex()->clone(); - chillAST_ArraySubscriptExpr *ASE = new chillAST_ArraySubscriptExpr(b, i, imwrittento, uniquePtr); - ASE->setParent(parent); - ASE->imreadfrom = false; // don't know this yet - ASE->isFromSourceFile = isFromSourceFile; - if (filename) ASE->filename = strdup(filename); - return ASE; -} - -void chillAST_ArraySubscriptExpr::gatherArrayRefs(std::vector &refs, bool writtento) { - if (!imwrittento) imwrittento = writtento; // may be both written and not for += TODO Purpose unclear - getIndex()->gatherArrayRefs(refs, 0); // recurse first - refs.push_back(this); -} - -void chillAST_ArraySubscriptExpr::gatherScalarRefs(std::vector &refs, bool writtento) { - chillAST_Node::gatherScalarRefs(refs, false); -} - -bool chillAST_ArraySubscriptExpr::operator!=(const chillAST_ArraySubscriptExpr &other) { - bool opposite = *this == other; - return !opposite; -} - - -bool chillAST_ArraySubscriptExpr::operator==(const chillAST_ArraySubscriptExpr &other) { - return this->uniquePtr == other.uniquePtr; -} - -chillAST_MemberExpr::chillAST_MemberExpr() { - children.push_back(NULL); -} -chillAST_MemberExpr::chillAST_MemberExpr(chillAST_Node *bas, const char *mem, void *unique, - CHILLAST_MEMBER_EXP_TYPE t):chillAST_MemberExpr() { - setBase(bas); - if (mem) member = strdup(mem); - else - member = NULL; - uniquePtr = unique; - exptype = t; - - return; -} - -// TODO member can be another member expression, Right? - -class chillAST_Node *chillAST_MemberExpr::clone() { - chillAST_Node *b = getBase()->clone(); - char *m = strdup(member); - chillAST_MemberExpr *ME = new chillAST_MemberExpr(b, m, uniquePtr); - ME->isFromSourceFile = isFromSourceFile; - if (filename) ME->filename = strdup(filename); - return ME; -} - -bool chillAST_MemberExpr::operator!=(const chillAST_MemberExpr &other) { - bool opposite = *this == other; - return !opposite; -} - -bool chillAST_MemberExpr::operator==(const chillAST_MemberExpr &other) { - return this->uniquePtr == other.uniquePtr; -} - -chillAST_Node *chillAST_MemberExpr::multibase2() { /*fprintf(stderr, "ME MB2\n" );*/ return (chillAST_Node *) this; } - -chillAST_VarDecl *chillAST_MemberExpr::getUnderlyingVarDecl() { - CHILL_ERROR("chillAST_MemberExpr:getUnderlyingVarDecl()\n"); - print(); - exit(-1); - // find the member with the correct name - -} - - -chillAST_VarDecl *chillAST_MemberExpr::multibase() { - chillAST_VarDecl *vd = getBase()->multibase(); // ?? - - chillAST_RecordDecl *rd = vd->getStructDef(); - if (!rd) { - fprintf(stderr, "chillAST_MemberExpr::multibase() vardecl is not a struct??\n"); - fprintf(stderr, "vd "); - vd->print(); - fprintf(stderr, "vd "); - vd->dump(); - exit(-1); - } - // OK, we have the recorddecl that defines the structure - // now find the member with the correct name - chillAST_VarDecl *sub = rd->findSubpart(member); - if (!sub) { - fprintf(stderr, "can't find member %s in \n", member); - rd->print(); - } - return sub; -} - -chillAST_DeclRefExpr::chillAST_DeclRefExpr(const char *vartype, const char *varname, chillAST_Node *d) { - if (vartype) declarationType = strdup(vartype); - else declarationType = strdup("UNKNOWN"); - if (varname) declarationName = strdup(varname); - else declarationName = strdup("NONE"); - decl = d; -} - -chillAST_DeclRefExpr::chillAST_DeclRefExpr(chillAST_VarDecl *vd) { - declarationType = strdup(vd->vartype); - declarationName = strdup(vd->varname); - decl = vd; -} - - -chillAST_DeclRefExpr::chillAST_DeclRefExpr(chillAST_FunctionDecl *fd) { - declarationType = strdup(fd->returnType); - declarationName = strdup(fd->functionName); - decl = fd; -} - -class chillAST_Node *chillAST_DeclRefExpr::clone() { - chillAST_DeclRefExpr *DRE = new chillAST_DeclRefExpr(declarationType, declarationName, decl); - DRE->setParent(parent); - DRE->isFromSourceFile = isFromSourceFile; - if (filename) DRE->filename = strdup(filename); - return DRE; -} - - -void chillAST_DeclRefExpr::gatherVarDeclsMore(vector &decls) { - decl->gatherVarDeclsMore(decls); -} - -void chillAST_DeclRefExpr::gatherDeclRefExprs(vector &refs) { - refs.push_back(this); -} - -void chillAST_DeclRefExpr::gatherScalarRefs(std::vector &refs, bool writtento) { - refs.push_back(this); -} - -void chillAST_DeclRefExpr::gatherVarUsage(vector &decls) { - for (int i = 0; i < decls.size(); i++) { - if (decls[i] == decl) { - return; - } - if (streq(declarationName, decls[i]->varname)) { - if (streq(declarationType, decls[i]->vartype)) { - CHILL_ERROR("Deprecated\n"); - return; - } - } - } - chillAST_VarDecl *vd = getVarDecl(); // null for functiondecl - if (vd) decls.push_back(vd); -} - - -void chillAST_DeclRefExpr::replaceVarDecls(chillAST_VarDecl *olddecl, chillAST_VarDecl *newdecl) { - if (decl == olddecl) { - decl = newdecl; - declarationType = strdup(newdecl->vartype); - declarationName = strdup(newdecl->varname); - } else { - CHILL_ERROR("Deprecated\n"); - if (!strcmp(olddecl->varname, declarationName)) { - decl = newdecl; - declarationType = strdup(newdecl->vartype); - declarationName = strdup(newdecl->varname); - } - } -} - -chillAST_VarDecl *chillAST_ImplicitCastExpr::multibase() { - return getSubExpr()->multibase(); -} - - -chillAST_VarDecl *chillAST_DeclRefExpr::multibase() { - // presumably, this is being called because this DRE is the base of an ArraySubscriptExpr - return getVarDecl(); -} - - -void chillAST_VarDecl::gatherVarDecls(vector &decls) { - for (int i = 0; i < decls.size(); i++) { - if (decls[i] == this) { - return; - } - if (streq(decls[i]->varname, varname)) { - if (streq(decls[i]->vartype, vartype)) { - CHILL_ERROR("Wrong\n"); - return; - } - } - } - decls.push_back(this); -} - - -void chillAST_VarDecl::gatherScalarVarDecls(vector &decls) { - if (numdimensions != 0) return; // not a scalar - - for (int i = 0; i < decls.size(); i++) { - if (decls[i] == this) { - return; - } - if (streq(decls[i]->varname, varname)) { // wrong. scoping. TODO - if (streq(decls[i]->vartype, vartype)) { - CHILL_ERROR("Wrong\n"); - return; - } - } - } - decls.push_back(this); -} - - -void chillAST_VarDecl::gatherArrayVarDecls(vector &decls) { - if (numdimensions == 0) return; // not an array - - for (int i = 0; i < decls.size(); i++) { - if (decls[i] == this) { - return; - } - - if (streq(decls[i]->varname, varname)) { // wrong. scoping. TODO - if (streq(decls[i]->vartype, vartype)) { - CHILL_ERROR("Wrong\n"); - return; - } - } - } - decls.push_back(this); -} - - -chillAST_Node *chillAST_VarDecl::clone() { - chillAST_VarDecl *vd = new chillAST_VarDecl(vartype, strdup(varname), arraypart, - NULL); // NULL so we don't add the variable AGAIN to the (presumably) function - - vd->typedefinition = typedefinition; - vd->vardef = vardef; // perhaps should not do this TODO - //vd->isStruct = (vardef != NULL); // ?? - - vd->underlyingtype = strdup(underlyingtype); - - vd->arraysizes = NULL; - vd->knownArraySizes = knownArraySizes; - vd->numdimensions = numdimensions; - vd->arraypointerpart = NULL; - - if (arraypart != NULL && NULL != arraysizes) { // !strcmp(arraypart, "")) { - vd->numdimensions = numdimensions; - - if (arraysizes) { - vd->arraysizes = (int *) malloc(sizeof(int *) * numdimensions); - for (int i = 0; i < numdimensions; i++) - vd->arraysizes[i] = arraysizes[i]; - } - } - - if (arraypointerpart) - vd->arraypointerpart = strdup(arraypointerpart); - - vd->isStruct = this->isStruct; - vd->knownArraySizes = this->knownArraySizes; - vd->isFromSourceFile = isFromSourceFile; - if (filename) vd->filename = strdup(filename); - return vd; -} - - -void chillAST_VarDecl::splitarraypart() { - if (arraypart) CHILL_DEBUG_PRINT("%s\n", arraypart); - - // split arraypart into (leading??) asterisks and known sizes [1][2][3] - if (!arraypart || // NULL - (arraypart && (*arraypart == '\0'))) { // or empty string - - // parts are both empty string - if (arraypointerpart) free(arraypointerpart); - arraypointerpart = strdup(""); - if (arraysetpart) free(arraysetpart); - arraysetpart = strdup(""); - return; - } - - // arraypart exists and is not empty - int asteriskcount = 0; - int fixedcount = 0; - for (int i = 0; i < strlen(arraypart); i++) { - if (arraypart[i] == '*') { - if (fixedcount) { - CHILL_ERROR("illegal vardecl arraypart: '%s'\n", arraypart); - exit(-1); - exit(-1); - } - asteriskcount++; - } else { // remainder is fixed? - fixedcount++; - // check for brackets and digits only? TODO - } - } - arraypointerpart = (char *) calloc(asteriskcount + 1, sizeof(char)); - arraysetpart = (char *) calloc(fixedcount + 1, sizeof(char)); - char *ptr = arraypart; - for (int i = 0; i < asteriskcount; i++) arraypointerpart[i] = *ptr++; - for (int i = 0; i < fixedcount; i++) arraysetpart[i] = *ptr++; -} - - -chillAST_IntegerLiteral::chillAST_IntegerLiteral(int val) { - value = val; - isFromSourceFile = true; // default - filename = NULL; -} - -class chillAST_Node *chillAST_IntegerLiteral::clone() { - - chillAST_IntegerLiteral *IL = new chillAST_IntegerLiteral(value); - IL->isFromSourceFile = isFromSourceFile; - if (filename) IL->filename = strdup(filename); - return IL; - -} - -chillAST_FloatingLiteral::chillAST_FloatingLiteral(double val, int precis, const char *printthis) { - value = val; - precision = precis; - allthedigits = NULL; - if (printthis) - allthedigits = strdup(printthis); - isFromSourceFile = true; - filename = NULL; -} - - -chillAST_FloatingLiteral::chillAST_FloatingLiteral(chillAST_FloatingLiteral *old) { - value = old->value; - allthedigits = NULL; - if (old->allthedigits) allthedigits = strdup(old->allthedigits); - precision = old->precision; - isFromSourceFile = true; // default - filename = NULL; -} - -chillAST_Node *chillAST_FloatingLiteral::clone() { - chillAST_FloatingLiteral *newone = new chillAST_FloatingLiteral(this); - newone->isFromSourceFile = isFromSourceFile; - if (filename) newone->filename = strdup(filename); - return newone; -} - -chillAST_UnaryOperator::chillAST_UnaryOperator() { - children.push_back(NULL); -} - -chillAST_UnaryOperator::chillAST_UnaryOperator(const char *oper, bool pre, chillAST_Node *sub) - : chillAST_UnaryOperator() { - op = strdup(oper); - prefix = pre; - setSubExpr(sub); - isFromSourceFile = true; // default - filename = NULL; -} - -void chillAST_UnaryOperator::gatherArrayRefs(std::vector &refs, bool w) { - getSubExpr()->gatherArrayRefs(refs, isAssignmentOp()); // -} - -void chillAST_UnaryOperator::gatherVarLHSUsage(vector &decls) { - if (isAssignmentOp()) { - getSubExpr()->gatherVarUsage(decls); // do all unary modify the subexpr? (no, - ) - } -} - - -chillAST_Node *chillAST_UnaryOperator::constantFold() { - chillAST_Node::constantFold(); - - chillAST_Node *returnval = this; - if (getSubExpr()->isConstant()) { - if (streq(op, "-")) { - if (getSubExpr()->isIntegerLiteral()) { - int intval = ((chillAST_IntegerLiteral *) getSubExpr())->value; - chillAST_IntegerLiteral *I = new chillAST_IntegerLiteral(-intval); - I->setParent(parent); - returnval = I; - } else { - chillAST_FloatingLiteral *FL = (chillAST_FloatingLiteral *) getSubExpr(); - chillAST_FloatingLiteral *F = (chillAST_FloatingLiteral*)(FL->clone()); // clone - F->value = -F->value; - returnval = F; - } - } else CHILL_DEBUG_PRINT("can't fold op '%s' yet\n", op); - } - return returnval; -} - - -class chillAST_Node *chillAST_UnaryOperator::clone() { - chillAST_UnaryOperator *UO = new chillAST_UnaryOperator(op, prefix, getSubExpr()->clone()); - UO->setParent(parent); - UO->isFromSourceFile = isFromSourceFile; - if (filename) UO->filename = strdup(filename); - return UO; -} - -int chillAST_UnaryOperator::evalAsInt() { - if (!strcmp("+", op)) return getSubExpr()->evalAsInt(); - if (!strcmp("-", op)) return -getSubExpr()->evalAsInt(); - if (!strcmp("++", op)) return 1 + getSubExpr()->evalAsInt(); - if (!strcmp("--", op)) return getSubExpr()->evalAsInt() - 1; - - fprintf(stderr, "chillAST_UnaryOperator::evalAsInt() unhandled op '%s'\n", op); - exit(-1); -} - -chillAST_ImplicitCastExpr::chillAST_ImplicitCastExpr() { - children.push_back(NULL); -} - -chillAST_Node* chillAST_ImplicitCastExpr::constantFold() { - chillAST_Node::constantFold(); - return getSubExpr(); -} - -chillAST_ImplicitCastExpr::chillAST_ImplicitCastExpr(chillAST_Node *sub) : chillAST_ImplicitCastExpr() { - setSubExpr(sub); -} - -class chillAST_Node *chillAST_ImplicitCastExpr::clone() { - chillAST_ImplicitCastExpr *ICE = new chillAST_ImplicitCastExpr(getSubExpr()->clone()); - ICE->isFromSourceFile = isFromSourceFile; - if (filename) ICE->filename = strdup(filename); - return ICE; -} - -chillAST_CStyleCastExpr::chillAST_CStyleCastExpr() { - children.push_back(NULL); -} - -chillAST_CStyleCastExpr::chillAST_CStyleCastExpr(const char *to, chillAST_Node *sub) : chillAST_CStyleCastExpr() { - towhat = strdup(to); - setSubExpr(sub); -} - -chillAST_Node * chillAST_CStyleCastExpr::constantFold() { - chillAST_Node::constantFold(); - if (getSubExpr()->isConstant()) { - double val; - if (getSubExpr() -> isIntegerLiteral()) { - val = getSubExpr()->evalAsInt(); - } else if (getSubExpr() -> isFloatingLiteral()) { - val = ((chillAST_FloatingLiteral*)getSubExpr())->value; - } else return this; - if (!strcmp(towhat,"float")) - return new chillAST_FloatingLiteral(val,1,NULL); - if (!strcmp(towhat, "double")) - return new chillAST_FloatingLiteral(val,2,NULL); - } - return this; -} - -class chillAST_Node *chillAST_CStyleCastExpr::clone() { - chillAST_CStyleCastExpr *CSCE = new chillAST_CStyleCastExpr(towhat, getSubExpr()->clone()); - CSCE->setParent(getParent()); - CSCE->isFromSourceFile = isFromSourceFile; - if (filename) CSCE->filename = strdup(filename); - return CSCE; -} - -chillAST_CStyleAddressOf::chillAST_CStyleAddressOf() { - children.push_back(NULL); -} - -chillAST_CStyleAddressOf::chillAST_CStyleAddressOf(chillAST_Node *sub) : chillAST_CStyleAddressOf() { - setSubExpr(sub); -} - -class chillAST_Node *chillAST_CStyleAddressOf::clone() { - chillAST_CStyleAddressOf *CSAO = new chillAST_CStyleAddressOf(getSubExpr()->clone()); - CSAO->setParent(getParent()); - CSAO->isFromSourceFile = isFromSourceFile; - if (filename) CSAO->filename = strdup(filename); - return CSAO; -} - -chillAST_Malloc::chillAST_Malloc() { - children.push_back(NULL); -} - -chillAST_Malloc::chillAST_Malloc(chillAST_Node *numthings) : chillAST_Malloc() { - setSize(numthings); - isFromSourceFile = true; // default - filename = NULL; -}; - -chillAST_Node *chillAST_Malloc::clone() { - chillAST_Malloc *M = new chillAST_Malloc(getSize()->clone()); // the general version - M->setParent(getParent()); - M->isFromSourceFile = isFromSourceFile; - if (filename) M->filename = strdup(filename); - return M; -}; - -chillAST_CudaMalloc::chillAST_CudaMalloc() { - children.push_back(NULL); - children.push_back(NULL); -} - -chillAST_CudaMalloc::chillAST_CudaMalloc(chillAST_Node *devmemptr, chillAST_Node *size) : chillAST_CudaMalloc() { - setDevPtr(devmemptr); - setSize(size); -}; - -class chillAST_Node *chillAST_CudaMalloc::clone() { - chillAST_CudaMalloc *CM = new chillAST_CudaMalloc(getDevPtr()->clone(), getSize()->clone()); - CM->setParent(getParent()); - CM->isFromSourceFile = isFromSourceFile; - if (filename) CM->filename = strdup(filename); - return CM; -} - -void chillAST_CudaMalloc::gatherArrayRefs(std::vector &refs, bool w) { - chillAST_Node::gatherArrayRefs(refs, false); -} - -void chillAST_CudaMalloc::gatherScalarRefs(std::vector &refs, bool writtento) { - chillAST_Node::gatherScalarRefs(refs, false); -} - -chillAST_CudaFree::chillAST_CudaFree() { - children.push_back(NULL); -} - -chillAST_CudaFree::chillAST_CudaFree(chillAST_Node *var) : chillAST_CudaFree() { - setParent(var); -}; - -class chillAST_Node *chillAST_CudaFree::clone() { - chillAST_CudaFree *CF = new chillAST_CudaFree(getPointer()->clone()); - CF->setParent(getParent()); - CF->isFromSourceFile = isFromSourceFile; - if (filename) CF->filename = strdup(filename); - return CF; -} - -chillAST_CudaMemcpy::chillAST_CudaMemcpy() { - addChild(NULL); - addChild(NULL); - addChild(NULL); -} - -chillAST_CudaMemcpy::chillAST_CudaMemcpy(chillAST_Node *d, chillAST_Node *s, chillAST_Node *siz, char *kind) { - setDest(d); - setSrc(s); - setSize(siz); - cudaMemcpyKind = kind; -}; - -class chillAST_Node *chillAST_CudaMemcpy::clone() { - chillAST_CudaMemcpy *CMCPY = new chillAST_CudaMemcpy(getDest()->clone(), - getSrc()->clone(), getSize()->clone(), - strdup(cudaMemcpyKind)); - CMCPY->setParent(getParent()); - CMCPY->isFromSourceFile = isFromSourceFile; - if (filename) CMCPY->filename = strdup(filename); - return CMCPY; -} - -void chillAST_CudaMemcpy::gatherArrayRefs(std::vector &refs, bool w) { - chillAST_Node::gatherArrayRefs(refs, false); -} - -void chillAST_CudaMemcpy::gatherScalarRefs(std::vector &refs, bool writtento) { - chillAST_Node::gatherScalarRefs(refs, false); -} - -chillAST_CudaSyncthreads::chillAST_CudaSyncthreads() { -} - -chillAST_ReturnStmt::chillAST_ReturnStmt() { - children.push_back(NULL); -} - -chillAST_ReturnStmt::chillAST_ReturnStmt(chillAST_Node *retval) : chillAST_ReturnStmt() { - setRetVal(retval); -} - -class chillAST_Node *chillAST_ReturnStmt::clone() { - chillAST_Node *val = NULL; - if (getRetVal()) val = getRetVal()->clone(); - chillAST_ReturnStmt *RS = new chillAST_ReturnStmt(val); - RS->setParent(getParent()); - RS->isFromSourceFile = isFromSourceFile; - if (filename) RS->filename = strdup(filename); - return RS; -} - -chillAST_CallExpr::chillAST_CallExpr() { - children.push_back(NULL); -} - -chillAST_CallExpr::chillAST_CallExpr(chillAST_Node *c) : chillAST_CallExpr() { - setCallee(c); - grid = block = NULL; -} - -chillAST_Node *chillAST_CallExpr::clone() { - chillAST_CallExpr *CE = new chillAST_CallExpr(getCallee()->clone()); - for (int i = 1; i < getNumChildren(); i++) CE->addArg(getChild(i)->clone()); - CE->isFromSourceFile = isFromSourceFile; - if (filename) CE->filename = strdup(filename); - return CE; -} - - -chillAST_VarDecl::chillAST_VarDecl() { - vartype = underlyingtype = varname = arraypart = arraypointerpart = arraysetpart = NULL; - typedefinition = NULL; - init = NULL; - numdimensions = 0; - arraysizes = NULL; - parent = NULL; - metacomment = NULL; - vardef = NULL; - isStruct = false; - isAParameter = false; - byreference = false; - isABuiltin = false; - isRestrict = isDevice = isShared = false; - knownArraySizes = false; -}; - - -chillAST_VarDecl::chillAST_VarDecl(const char *t, const char *n, const char *a) { - vartype = strdup(t); - typedefinition = NULL; - - underlyingtype = parseUnderlyingType(vartype); - varname = strdup(n); - arraypointerpart = arraysetpart = NULL; - if (a) arraypart = strdup(a); - else arraypart = strdup(""); - splitarraypart(); - - init = NULL; - numdimensions = 0; - arraysizes = NULL; - uniquePtr = NULL; - - knownArraySizes = false; - for (int i = 0; i < strlen(a); i++) { - if (a[i] == '[') { - numdimensions++; - knownArraySizes = true; - } - if (!knownArraySizes && a[i] == '*') numdimensions++; - } - - vardef = NULL; - isStruct = false; - - //insideAStruct = false; - isAParameter = false; - byreference = false; - isABuiltin = false; - isRestrict = isDevice = isShared = false; // fprintf(stderr, "RDS = false\n"); -}; - - -chillAST_VarDecl::chillAST_VarDecl(chillAST_RecordDecl *astruct, const char *nam, const char *array) { - // define a variable whose type is a struct! - const char *type = astruct->getName(); - - vartype = strdup(type); - - // these always go together ?? - vardef = astruct;// pointer to the thing that says what is inside the struct - isStruct = true; // ?? wrong if it's a union ?? TODO - - underlyingtype = parseUnderlyingType(vartype); - varname = strdup(nam); - arraypart = strdup(array); - arraypointerpart = arraysetpart = NULL; - splitarraypart(); - - init = NULL; - numdimensions = 0; - arraysizes = NULL; - uniquePtr = NULL; - - knownArraySizes = false; - for (int i = 0; i < strlen(array); i++) { - if (array[i] == '[') { - numdimensions++; - knownArraySizes = true; - } - if (!knownArraySizes && array[i] == '*') numdimensions++; - } - - isAParameter = false; - fprintf(stderr, "%s is NOT a parameter\n", nam); - byreference = false; - isABuiltin = false; - isRestrict = isDevice = isShared = false; // fprintf(stderr, "RDS = false\n"); - typedefinition = NULL; -}; - - -chillAST_VarDecl::chillAST_VarDecl(chillAST_TypedefDecl *tdd, const char *n, const char *a) { - const char *type = tdd->getStructName(); - typedefinition = tdd; - vartype = strdup(type); - underlyingtype = parseUnderlyingType(vartype); - varname = strdup(n); - arraypart = strdup(a); - arraypointerpart = arraysetpart = NULL; - splitarraypart(); - - init = NULL; - numdimensions = 0; - arraysizes = NULL; - uniquePtr = NULL; - knownArraySizes = false; - for (int i = 0; i < strlen(a); i++) { - if (a[i] == '[') { - numdimensions++; - knownArraySizes = true; - } - if (!knownArraySizes && a[i] == '*') numdimensions++; - } - isStruct = tdd->isAStruct(); - vardef = NULL; - isAParameter = false; - byreference = false; - isABuiltin = false; - isRestrict = isDevice = isShared = false; -}; - - -chillAST_VarDecl::chillAST_VarDecl(const char *t, const char *n, const char *a, void *ptr) { - CHILL_DEBUG_PRINT("chillAST_VarDecl::chillAST_VarDecl( type %s, name %s, arraypart '%s' ) %p\n", t, n, a, this); - vartype = strdup(t); - typedefinition = NULL; - underlyingtype = parseUnderlyingType(vartype); - varname = strdup(n); - vardef = NULL; // not a struct - isStruct = false; - isAParameter = false; - if (a) arraypart = strdup(a); - else arraypart = strdup(""); // should catch this earlier - arraypointerpart = arraysetpart = NULL; - splitarraypart(); - init = NULL; - numdimensions = 0; - arraysizes = NULL; - uniquePtr = ptr; - knownArraySizes = false; - - for (int i = 0; i < strlen(a); i++) { - if (a[i] == '[') { - numdimensions++; - knownArraySizes = true; - } - if (!knownArraySizes && a[i] == '*') numdimensions++; // fails for a[4000 * 4] - } - // this is from ir_clang.cc ConvertVarDecl(), that got executed AFTER the vardecl was constructed. dumb - int numdim = 0; - //knownArraySizes = true; - //if (index(vartype, '*')) knownArraySizes = false; // float *a; for example - //if (index(arraypart, '*')) knownArraySizes = false; - - // note: vartype here, arraypart in next code.. is that right? - if (index(vartype, '*')) { - for (int i = 0; i < strlen(vartype); i++) if (vartype[i] == '*') numdim++; - numdimensions = numdim; - } - - if (index(arraypart, '[')) { // JUST [12][34][56] no asterisks - char *dupe = strdup(arraypart); - - int len = strlen(arraypart); - for (int i = 0; i < len; i++) if (dupe[i] == '[') numdim++; - - numdimensions = numdim; - int *as = (int *) malloc(sizeof(int *) * numdim); - if (!as) { - CHILL_ERROR("can't malloc array sizes in ConvertVarDecl()\n"); - exit(-1); - } - arraysizes = as; // 'as' changed later! - - - char *ptr = dupe; - while (ptr = index(ptr, '[')) { // this fails for float a[4000*4] - ptr++; - char *leak = strdup(ptr); - char *close = index(leak, ']'); - if (close) *close = '\0'; - - int l = strlen(leak); - bool justdigits = true; - bool justmath = true; - for (int i = 0; i < l; i++) { - char c = leak[i]; - if (!isdigit(c)) justdigits = false; - if (!(isdigit(c) || - isblank(c) || - ((c == '+') || (c == '*') || (c == '*') || (c == '*')) || // math - ((c == '(') || (c == ')'))) - ) { - justmath = false; - } - } - if (justdigits) { - int dim; - sscanf(ptr, "%d", &dim); - *as++ = dim; - } else { - if (justmath) fprintf(stderr, "JUST MATH\n"); - fprintf(stderr, "need to evaluate %s, faking with hardcoded 16000\n", leak); - *as++ = 16000; // temp TODO DFL - } - free(leak); - ptr = index(ptr, ']'); - } - free(dupe); - } - - byreference = false; - isABuiltin = false; - isRestrict = isDevice = isShared = false; - // currently this is bad, because a struct does not have a symbol table, so the - // members of a struct are passed up to the func or sourcefile. -}; - -chillAST_RecordDecl *chillAST_VarDecl::getStructDef() { - if (vardef) return vardef; - if (typedefinition) return typedefinition->getStructDef(); - return NULL; -} - - -chillAST_CompoundStmt::chillAST_CompoundStmt() { - parent = NULL; - symbolTable = new chillAST_SymbolTable; - typedefTable = new chillAST_TypedefTable; -}; - -void chillAST_CompoundStmt::replaceChild(chillAST_Node *old, chillAST_Node *newchild) { - vector dupe = children; - int numdupe = dupe.size(); - int any = 0; - - for (int i = 0; i < numdupe; i++) { - if (dupe[i] == old) { - children[i] = newchild; - newchild->setParent(this); - any = 1; - } - } - - if (!any) { - CHILL_ERROR("chillAST_CompoundStmt::replaceChild(), could not find old\n"); - exit(-1); - } -} - -chillAST_Node *chillAST_CompoundStmt::clone() { - chillAST_CompoundStmt *cs = new chillAST_CompoundStmt(); - for (int i = 0; i < children.size(); i++) cs->addChild(children[i]->clone()); - cs->setParent(getParent()); - cs->isFromSourceFile = isFromSourceFile; - if (filename) cs->filename = strdup(filename); - return cs; -} - -void chillAST_CompoundStmt::gatherArrayRefs(std::vector &refs, bool writtento) { - chillAST_Node::gatherArrayRefs(refs,false); -} - -void chillAST_CompoundStmt::gatherScalarRefs(std::vector &refs, bool writtento) { - chillAST_Node::gatherScalarRefs(refs,false); -} - -bool chillAST_CompoundStmt::findLoopIndexesToReplace(chillAST_SymbolTable *symtab, bool forcesync) { - - // see how many elements we currently have - int sofar = children.size(); - - // make big enough to add a sync after each statement. wasteful. TODO - // this prevents inserts happening at the forstmt::addSync() from causing a - // reallocation, which screwsup the loop below here - children.reserve(2 * sofar); - - bool force = false; - for (int i = 0; i < children.size(); i++) { // children.size() to see it gain each time - if (children.size() > sofar) - sofar = children.size(); - - bool thisforces = children[i]->findLoopIndexesToReplace(symtab, force); - force = force || thisforces; // once set, always - } - return false; - -/* - vector childrencopy; - for (int i=0; igetTypeString() ); - origtypes[i] = strdup( children[i]->getTypeString() ); - fprintf(stderr, "ORIGINAL compound child %d of type %s\n", i, children[i]->getTypeString() ); - } - - for (int i=0; igetTypeString(), force ); - force = force || childrencopy[i]->findLoopIndexesToReplace( symtab, force ); // once set, always - } - - fprintf(stderr, "\n"); - for (int i=0; igetTypeString() ); - } - - return false; -*/ -} - -chillAST_ParenExpr::chillAST_ParenExpr() { - children.push_back(NULL); -} - -chillAST_ParenExpr::chillAST_ParenExpr(chillAST_Node *sub):chillAST_ParenExpr() { - setSubExpr(sub); -} - -chillAST_Node *chillAST_ParenExpr::clone() { - chillAST_ParenExpr *PE = new chillAST_ParenExpr(getSubExpr()->clone()); - PE->setParent(getParent()); - PE->isFromSourceFile = isFromSourceFile; - if (filename) PE->filename = strdup(filename); - return PE; -} - -chillAST_Sizeof::chillAST_Sizeof(char *athing) { - thing = strdup(athing); // memory leak -} - -chillAST_Node *chillAST_Sizeof::clone() { - chillAST_Sizeof *SO = new chillAST_Sizeof(thing); - SO->setParent(getParent()); - SO->isFromSourceFile = isFromSourceFile; - if (filename) SO->filename = strdup(filename); - return SO; -} - -chillAST_IfStmt::chillAST_IfStmt() { - children.push_back(NULL); - children.push_back(NULL); - children.push_back(NULL); -} - -chillAST_IfStmt::chillAST_IfStmt(chillAST_Node *c, chillAST_Node *t, chillAST_Node *e) : chillAST_IfStmt() { - setCond(c); - setThen(t); - setElse(e); -} - -void chillAST_IfStmt::gatherArrayRefs(std::vector &refs, bool writtento) { - chillAST_Node::gatherArrayRefs(refs, false); -} - -void chillAST_IfStmt::gatherScalarRefs(std::vector &refs, bool writtento) { - chillAST_Node::gatherScalarRefs(refs, false); -} - -chillAST_Node *chillAST_IfStmt::clone() { - chillAST_Node *c, *t, *e; - c = t = e = NULL; - if (getCond()) c = getCond()->clone(); // has to be one, right? - if (getThen()) t = getThen()->clone(); - if (getElse()) e = getElse()->clone(); - - chillAST_IfStmt *IS = new chillAST_IfStmt(c, t, e); - IS->setParent(getParent()); - IS->isFromSourceFile = isFromSourceFile; - if (filename) IS->filename = strdup(filename); - return IS; -} - -bool chillAST_IfStmt::findLoopIndexesToReplace(chillAST_SymbolTable *symtab, bool forcesync) { - getThen()->findLoopIndexesToReplace(symtab); - getElse()->findLoopIndexesToReplace(symtab); - return false; // ?? -} - -chillAST_Node *minmaxTernary(const char * op, chillAST_Node *left, chillAST_Node *right) { - - chillAST_Node *lp1 = left->clone(); - chillAST_Node *rp1 = right->clone(); - chillAST_BinaryOperator *cond = new chillAST_BinaryOperator(lp1, op, rp1); - chillAST_Node *lp2 = left->clone(); - chillAST_Node *rp2 = right->clone(); - - return new chillAST_TernaryOperator("?", cond, lp2, rp2); -} - -// look for function declaration with a given name, in the tree with root "node" -void findFunctionDeclRecursive(chillAST_Node *node, const char *procname, vector &funcs) { - if (node->isFunctionDecl()) { - char *name = ((chillAST_FunctionDecl *) node)->functionName; // compare name with desired name - if (!strcmp(name, procname)) { - funcs.push_back((chillAST_FunctionDecl *) node); // this is it - return; - } - } - // this is where the children can be used effectively. - // we don't really care what kind of node we're at. We just check the node itself - // and then its children is needed. - int numc = node->getNumChildren(); - for (int i = 0; i < numc; i++) { - if (node->isSourceFile()) - if (node->getChild(i)->isFunctionDecl()) - chillAST_FunctionDecl *fd = (chillAST_FunctionDecl *) node->getChild(i); - findFunctionDeclRecursive(node->getChild(i), procname, funcs); - } - return; -} - -chillAST_SymbolTable *addSymbolToTable(chillAST_SymbolTable *st, chillAST_VarDecl *vd) // definition -{ - chillAST_SymbolTable *s = st; - if (!s) s = new chillAST_SymbolTable; - int tablesize = s->size(); - for (int i = 0; i < tablesize; i++) { - if ((*s)[i] == vd) { - return s; // already there - } - } - for (int i = 0; i < tablesize; i++) { - if (!strcmp((*s)[i]->varname, vd->varname)) { - return s; // already there - } - } - s->push_back(vd); // add it - return s; -} - -chillAST_TypedefTable *addTypedefToTable(chillAST_TypedefTable *tdt, chillAST_TypedefDecl *td) { - - chillAST_TypedefTable *t = tdt; - if (!t) t = new chillAST_TypedefTable; - - int tablesize = t->size(); - - for (int i = 0; i < tablesize; i++) { - if ((*t)[i] == td) return t; // already there - } - t->push_back(td); // add it - return t; -} - - -chillAST_NoOp::chillAST_NoOp() { -}; // so we have SOMETHING for NoOp in the cc file ??? - - -chillAST_Preprocessing::chillAST_Preprocessing() { - position = CHILLAST_PREPROCESSING_POSITIONUNKNOWN; - pptype = CHILLAST_PREPROCESSING_TYPEUNKNOWN; - blurb = strdup(""); // never use null. ignore the leak ?? -} - - -chillAST_Preprocessing::chillAST_Preprocessing(CHILLAST_PREPROCESSING_POSITION pos, - CHILLAST_PREPROCESSING_TYPE t, - char *text) { - position = pos; - pptype = t; - blurb = strdup(text); -} - diff --git a/src/frontend/clang.cpp b/src/frontend/clang.cpp new file mode 100644 index 0000000..e7b74ed --- /dev/null +++ b/src/frontend/clang.cpp @@ -0,0 +1,790 @@ +// +// Created by ztuowen on 10/10/16. +// + +#include +#include +#include "ir_chill.hh" +#include "loop.hh" +#include "chill_error.hh" + +#include "clang/Frontend/FrontendActions.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "code_gen/CG_chillRepr.h" +#include "code_gen/CG_chillBuilder.h" +#include +#include + +#include "chillAST.h" + +using namespace clang; +using namespace clang::driver; +using namespace omega; +using namespace std; + +#define NL_RET(x) {chillAST_NodeList *ret = new chillAST_NodeList(); \ + ret->push_back(x); \ + return ret;} + +static string binops[] = { + " ", " ", // BO_PtrMemD, BO_PtrMemI, // [C++ 5.5] Pointer-to-member operators. + "*", "/", "%", // BO_Mul, BO_Div, BO_Rem, // [C99 6.5.5] Multiplicative operators. + "+", "-", // BO_Add, BO_Sub, // [C99 6.5.6] Additive operators. + "<<", ">>", // BO_Shl, BO_Shr, // [C99 6.5.7] Bitwise shift operators. + "<", ">", "<=", ">=", // BO_LT, BO_GT, BO_LE, BO_GE, // [C99 6.5.8] Relational operators. + "==", "!=", // BO_EQ, BO_NE, // [C99 6.5.9] Equality operators. + "&", // BO_And, // [C99 6.5.10] Bitwise AND operator. + "??", // BO_Xor, // [C99 6.5.11] Bitwise XOR operator. + "|", // BO_Or, // [C99 6.5.12] Bitwise OR operator. + "&&", // BO_LAnd, // [C99 6.5.13] Logical AND operator. + "||", // BO_LOr, // [C99 6.5.14] Logical OR operator. + "=", "*=", // BO_Assign, BO_MulAssign, // [C99 6.5.16] Assignment operators. + "/=", "%=", // BO_DivAssign, BO_RemAssign, + "+=", "-=", // BO_AddAssign, BO_SubAssign, + "???", "???", // BO_ShlAssign, BO_ShrAssign, + "&&=", "???", // BO_AndAssign, BO_XorAssign, + "||=", // BO_OrAssign, + ","}; // BO_Comma // [C99 6.5.17] Comma operator. + + +static string unops[] = { + "++", "--", // [C99 6.5.2.4] Postfix increment and decrement + "++", "--", // [C99 6.5.3.1] Prefix increment and decrement + "@", "*", // [C99 6.5.3.2] Address and indirection + "+", "-", // [C99 6.5.3.3] Unary arithmetic + "~", "!", // [C99 6.5.3.3] Unary arithmetic + "__real", "__imag", // "__real expr"/"__imag expr" Extension. + "__extension" // __extension__ marker. +}; + +chillAST_NodeList* ConvertTypeDefDecl(clang::TypedefDecl *TDD); + +chillAST_NodeList* ConvertRecordDecl(clang::RecordDecl *D); + +chillAST_NodeList* ConvertDeclStmt(clang::DeclStmt *clangDS); + +chillAST_NodeList* ConvertCompoundStmt(clang::CompoundStmt *clangCS); + +chillAST_NodeList* ConvertFunctionDecl(clang::FunctionDecl *D); + +chillAST_NodeList* ConvertForStmt(clang::ForStmt *clangFS); + +chillAST_NodeList* ConvertUnaryOperator(clang::UnaryOperator *clangU); + +chillAST_NodeList* ConvertBinaryOperator(clang::BinaryOperator *clangBO); + +chillAST_NodeList* ConvertArraySubscriptExpr(clang::ArraySubscriptExpr *clangASE); + +chillAST_NodeList* ConvertDeclRefExpr(clang::DeclRefExpr *clangDRE); + +chillAST_NodeList* ConvertIntegerLiteral(clang::IntegerLiteral *clangIL); + +chillAST_NodeList* ConvertFloatingLiteral(clang::FloatingLiteral *clangFL); + +chillAST_NodeList* ConvertImplicitCastExpr(clang::ImplicitCastExpr *clangICE); + +chillAST_NodeList* ConvertCStyleCastExpr(clang::CStyleCastExpr *clangICE); + +chillAST_NodeList* ConvertReturnStmt(clang::ReturnStmt *clangRS); + +chillAST_NodeList* ConvertCallExpr(clang::CallExpr *clangCE); + +chillAST_NodeList* ConvertIfStmt(clang::IfStmt *clangIS); + +chillAST_NodeList* ConvertMemberExpr(clang::MemberExpr *clangME); + + +chillAST_NodeList* ConvertTranslationUnit(clang::TranslationUnitDecl *TUD, char *filename); + +/*! + * \brief Convert fon Clang AST to CHiLL AST also append to parent node p if necessary + * + * @param s Clang statement + * @return A set of new statements + */ +chillAST_NodeList* ConvertGenericClangAST(clang::Stmt *s); + +// forward defs +SourceManager *globalSRCMAN; // ugly. shame. + +char *splitTypeInfo(char *underlyingtype); + +chillAST_Node* unwrap(chillAST_NodeList* nl){ + chillAST_Node* n; + if (!nl || !nl->size()) n = NULL; + else n = (*nl)[0]; + delete nl; + return n; +} + +chillAST_NodeList* ConvertVarDecl(VarDecl *D) { + bool isParm = false; + + QualType T0 = D->getType(); + QualType T = T0; + if (ParmVarDecl *Parm = dyn_cast(D)) { // My GOD clang stinks + T = Parm->getOriginalType(); + isParm = true; + } + + char *vartype = strdup(T.getAsString().c_str()); + char *arraypart = splitTypeInfo(vartype); + + char *varname = strdup(D->getName().str().c_str()); + + chillAST_VarDecl *chillVD = new chillAST_VarDecl(vartype, varname, arraypart, (void *) D); + + chillVD->isAParameter = isParm; + + int numdim = 0; + chillVD->knownArraySizes = true; + if (index(vartype, '*')) chillVD->knownArraySizes = false; // float *a; for example + if (index(arraypart, '*')) chillVD->knownArraySizes = false; + + // note: vartype here, arraypart in next code.. is that right? + if (index(vartype, '*')) { + for (int i = 0; i < strlen(vartype); i++) if (vartype[i] == '*') numdim++; + chillVD->numdimensions = numdim; + } + + if (index(arraypart, '[')) { // JUST [12][34][56] no asterisks + char *dupe = strdup(arraypart); + + int len = strlen(arraypart); + for (int i = 0; i < len; i++) if (dupe[i] == '[') numdim++; + + chillVD->numdimensions = numdim; + int *as = (int *) malloc(sizeof(int *) * numdim); + if (!as) { + fprintf(stderr, "can't malloc array sizes in ConvertVarDecl()\n"); + exit(-1); + } + chillVD->arraysizes = as; // 'as' changed later! + + + char *ptr = dupe; + while (ptr = index(ptr, '[')) { + ptr++; + int dim; + sscanf(ptr, "%d", &dim); + *as++ = dim; + + ptr = index(ptr, ']'); + } + free(dupe); + } + + Expr *Init = D->getInit(); + if (Init) { + fprintf(stderr, " = VARDECL HAS INIT. (TODO) (RIGHT NOW)"); + exit(-1); + } + + free(vartype); + free(varname); + + VariableDeclarations.push_back(chillVD); + + NL_RET(chillVD); +} + + +chillAST_NodeList* ConvertRecordDecl(clang::RecordDecl *RD) { // for structs and unions + int count = 0; + for (clang::RecordDecl::field_iterator fi = RD->field_begin(); fi != RD->field_end(); fi++) count++; + + char blurb[128]; + + chillAST_TypedefDecl *astruct = new chillAST_TypedefDecl(blurb, "", NULL); + astruct->setStruct(true); + astruct->setStructName(RD->getNameAsString().c_str()); + + for (clang::RecordDecl::field_iterator fi = RD->field_begin(); fi != RD->field_end(); fi++) { + clang::FieldDecl *FD = (*fi); + string TypeStr = FD->getType().getAsString(); + const char *typ = TypeStr.c_str(); + const char *name = FD->getNameAsString().c_str(); + chillAST_VarDecl *VD = NULL; + // very clunky and incomplete + VD = new chillAST_VarDecl(typ, name, "", astruct); // can't handle arrays yet + astruct->subparts.push_back(VD); + } + NL_RET(astruct); +} + + +chillAST_NodeList* ConvertTypeDefDecl(TypedefDecl *TDD) { + char *under = strdup(TDD->getUnderlyingType().getAsString().c_str()); + char *arraypart = splitTypeInfo(under); + char *alias = strdup(TDD->getName().str().c_str()); + chillAST_TypedefDecl *CTDD = new chillAST_TypedefDecl(under, alias, arraypart); + free(under); + free(arraypart); + NL_RET(CTDD); +} + + +chillAST_NodeList* ConvertDeclStmt(DeclStmt *clangDS) { + chillAST_VarDecl *chillvardecl; // the thing we'll return if this is a single declaration + bool multiples = !clangDS->isSingleDecl(); + DeclGroupRef dgr = clangDS->getDeclGroup(); + clang::DeclGroupRef::iterator DI = dgr.begin(); + clang::DeclGroupRef::iterator DE = dgr.end(); + chillAST_NodeList* decls = new chillAST_NodeList(); + for (; DI != DE; ++DI) { + Decl *D = *DI; + const char *declty = D->getDeclKindName(); + if (!strcmp("Var", declty)) { + VarDecl *V = dyn_cast(D); + std::string Name = V->getNameAsString(); + char *varname = strdup(Name.c_str()); + QualType T = V->getType(); + string TypeStr = T.getAsString(); + char *vartype = strdup(TypeStr.c_str()); + CHILL_DEBUG_PRINT("DeclStmt (clang 0x%x) for %s %s\n", D, vartype, varname); + char *arraypart = splitTypeInfo(vartype); + chillvardecl = new chillAST_VarDecl(vartype, varname, arraypart, (void *) D); + // store this away for declrefexpr that references it! + VariableDeclarations.push_back(chillvardecl); + decls->push_back(chillvardecl); + // TODO + if (V->hasInit()) { + CHILL_ERROR(" ConvertDeclStmt() UNHANDLED initialization\n"); + exit(-1); + } + } + } + return decls; +} + + +chillAST_NodeList* ConvertCompoundStmt(CompoundStmt *clangCS) { + // make an empty CHILL compound statement + chillAST_CompoundStmt *chillCS = new chillAST_CompoundStmt; + // for each clang child + for (auto I = clangCS->child_begin(); I != clangCS->child_end(); ++I) { // ?? loop looks WRONG + // create the chill ast for each child + Stmt *child = *I; + chillAST_NodeList* nl = ConvertGenericClangAST(child); + // usually n will be a statement. We just add it as a child. + // SOME DeclStmts have multiple declarations. They will add themselves and return NULL + chillCS->addChildren(*nl); + delete nl; + } + NL_RET(chillCS); +} + + +chillAST_NodeList* ConvertFunctionDecl(FunctionDecl *D) { + QualType QT = D->getReturnType(); + string ReturnTypeStr = QT.getAsString(); + // Function name + DeclarationName DeclName = D->getNameInfo().getName(); + string FuncName = DeclName.getAsString(); + chillAST_FunctionDecl *chillFD = new chillAST_FunctionDecl(ReturnTypeStr.c_str(), FuncName.c_str(), D); + + int numparams = D->getNumParams(); + CHILL_DEBUG_PRINT(" %d parameters\n", numparams); + for (int i = 0; i < numparams; i++) { + VarDecl *clangvardecl = D->getParamDecl(i); // the ith parameter (CLANG) + ParmVarDecl *pvd = D->getParamDecl(i); + QualType T = pvd->getOriginalType(); + CHILL_DEBUG_PRINT("OTYPE %s\n", T.getAsString().c_str()); + + chillAST_NodeList* nl = ConvertVarDecl(clangvardecl); + chillAST_VarDecl* decl = (chillAST_VarDecl*)unwrap(nl); + + VariableDeclarations.push_back(decl); + chillFD->addParameter(decl); + CHILL_DEBUG_PRINT("chillAST ParmVarDecl for %s from chill location 0x%x\n", decl->varname, clangvardecl); + } // for each parameter + + if (D->getBuiltinID()) { + chillFD->setExtern(); + CHILL_DEBUG_PRINT("%s is builtin (extern)\n", FuncName.c_str()); + }; + + Stmt *clangbody = D->getBody(); + if (clangbody) { + // may just be fwd decl or external, without an actual body + chillAST_NodeList* nl = ConvertGenericClangAST(clangbody); + chillFD->setBody(unwrap(nl)); + } + + FunctionDeclarations.push_back(chillFD); + NL_RET(chillFD); +} + + +chillAST_NodeList* ConvertForStmt(ForStmt *clangFS) { + chillAST_Node *init = unwrap(ConvertGenericClangAST(clangFS->getInit())); + chillAST_Node *cond = unwrap(ConvertGenericClangAST(clangFS->getCond())); + chillAST_Node *incr = unwrap(ConvertGenericClangAST(clangFS->getInc())); + chillAST_Node *body = unwrap(ConvertGenericClangAST(clangFS->getBody())); + if (body->getType() != CHILLAST_NODE_COMPOUNDSTMT) { + // make single statement loop bodies loop like other loops + CHILL_DEBUG_PRINT("ForStmt body of type %s\n", body->getTypeString()); + chillAST_CompoundStmt *cs = new chillAST_CompoundStmt(); + cs->addChild(body); + body = cs; + } + chillAST_ForStmt *chill_loop = new chillAST_ForStmt(init, cond, incr, body); + NL_RET(chill_loop); +} + + +chillAST_NodeList* ConvertIfStmt(IfStmt *clangIS) { + Expr *cond = clangIS->getCond(); + Stmt *thenpart = clangIS->getThen(); + Stmt *elsepart = clangIS->getElse(); + + chillAST_Node *con = unwrap(ConvertGenericClangAST(cond)); + chillAST_Node *thn = NULL; + if (thenpart) { + thn = unwrap(ConvertGenericClangAST(thenpart)); + if (!thn->isCompoundStmt()) { + chillAST_Node* tmp=new chillAST_CompoundStmt(); + tmp->addChild(thn); + thn = tmp; + } + } + chillAST_Node *els = NULL; + if (elsepart) { + els = unwrap(ConvertGenericClangAST(elsepart)); + if (!els->isCompoundStmt()) { + chillAST_Node* tmp=new chillAST_CompoundStmt(); + tmp->addChild(els); + els = tmp; + } + } + + chillAST_IfStmt *ifstmt = new chillAST_IfStmt(con, thn, els); + NL_RET(ifstmt); +} + + +chillAST_NodeList* ConvertUnaryOperator(UnaryOperator *clangUO) { + const char *op = unops[clangUO->getOpcode()].c_str(); + bool pre = clangUO->isPrefix(); + chillAST_Node *sub = unwrap(ConvertGenericClangAST(clangUO->getSubExpr())); + + chillAST_UnaryOperator *chillUO = new chillAST_UnaryOperator(op, pre, sub); + NL_RET(chillUO); +} + + +chillAST_NodeList* ConvertBinaryOperator(BinaryOperator *clangBO) { + + // get the clang parts + Expr *lhs = clangBO->getLHS(); + Expr *rhs = clangBO->getRHS(); + BinaryOperator::Opcode op = clangBO->getOpcode(); // this is CLANG op, not CHILL op + + + // convert to chill equivalents + chillAST_Node *l = unwrap(ConvertGenericClangAST(lhs)); + const char *opstring = binops[op].c_str(); + chillAST_Node *r = unwrap(ConvertGenericClangAST(rhs)); + // TODO chill equivalent for numeric op. + + // build up the chill Binary Op AST node + chillAST_BinaryOperator *binop = new chillAST_BinaryOperator(l, opstring, r); + + NL_RET(binop); +} + + +chillAST_NodeList* ConvertArraySubscriptExpr(ArraySubscriptExpr *clangASE) { + Expr *clangbase = clangASE->getBase(); + Expr *clangindex = clangASE->getIdx(); + + chillAST_Node *bas = unwrap(ConvertGenericClangAST(clangbase)); + chillAST_Node *indx = unwrap(ConvertGenericClangAST(clangindex)); + + // TODO clangAST contamination + chillAST_ArraySubscriptExpr *chillASE = new chillAST_ArraySubscriptExpr(bas, indx, NULL, clangASE); + NL_RET(chillASE); +} + + +chillAST_NodeList* ConvertDeclRefExpr(DeclRefExpr *clangDRE) { + DeclarationNameInfo DNI = clangDRE->getNameInfo(); + + ValueDecl *vd = static_cast(clangDRE->getDecl()); // ValueDecl ?? VarDecl ?? + + QualType QT = vd->getType(); + string TypeStr = QT.getAsString(); + + DeclarationName DN = DNI.getName(); + const char *varname = DN.getAsString().c_str(); + chillAST_DeclRefExpr *chillDRE = new chillAST_DeclRefExpr(TypeStr.c_str(), varname, NULL); + + // find the definition (we hope) TODO Wrong treatment + if ((!strcmp("Var", vd->getDeclKindName())) || (!strcmp("ParmVar", vd->getDeclKindName()))) { + // it's a variable reference + int numvars = VariableDeclarations.size(); + chillAST_VarDecl *chillvd = NULL; + for (int i = 0; i < numvars; i++) { + if (VariableDeclarations[i]->uniquePtr == vd) + chillvd = VariableDeclarations[i]; + } + if (!chillvd) { + fprintf(stderr, "\nWARNING, ir_clang.cc clang DeclRefExpr %s refers to a declaration I can't find! at ox%x\n", + varname, vd); + fprintf(stderr, "variables I know of are:\n"); + for (int i = 0; i < numvars; i++) { + chillAST_VarDecl *adecl = VariableDeclarations[i]; + if (adecl->isParmVarDecl()) fprintf(stderr, "(parameter) "); + fprintf(stderr, "%s %s at location 0x%x\n", adecl->vartype, adecl->varname, adecl->uniquePtr); + } + fprintf(stderr, "\n"); + } + + if (chillvd == NULL) { + CHILL_ERROR("chillDRE->decl = 0x%x\n", chillvd); + exit(-1); + } + + chillDRE->decl = (chillAST_Node *) chillvd; + } else if (!strcmp("Function", vd->getDeclKindName())) { + int numfuncs = FunctionDeclarations.size(); + chillAST_FunctionDecl *chillfd = NULL; + for (int i = 0; i < numfuncs; i++) { + if (FunctionDeclarations[i]->uniquePtr == vd) + chillfd = FunctionDeclarations[i]; + } + if (chillfd == NULL) { + CHILL_ERROR("chillDRE->decl = 0x%x\n", chillfd); + exit(-1); + } + chillDRE->decl = (chillAST_Node *) chillfd; + } else { + CHILL_ERROR("clang DeclRefExpr refers to declaration of %s of kind %s\n", varname, vd->getDeclKindName()); + exit(-1); + } + NL_RET(chillDRE); +} + + +chillAST_NodeList* ConvertIntegerLiteral(IntegerLiteral *clangIL) { + bool isSigned = clangIL->getType()->isSignedIntegerType(); + const char *printable = clangIL->getValue().toString(10, isSigned).c_str(); + int val = stoi(printable); + chillAST_IntegerLiteral *chillIL = new chillAST_IntegerLiteral(val); + NL_RET(chillIL); +} + + +chillAST_NodeList* ConvertFloatingLiteral(FloatingLiteral *clangFL) { + // Get an appriximate value of the APFloat + float val = clangFL->getValueAsApproximateDouble(); + SmallString<16> Str; + clangFL->getValue().toString(Str); + + SourceLocation sloc = clangFL->getLocStart(); + SourceLocation eloc = clangFL->getLocEnd(); + + std::string start = sloc.printToString(*globalSRCMAN); + const char *filename = globalSRCMAN->getBufferName(sloc); + + if (filename && strlen(filename) > 0) {} + else { + fprintf(stderr, "\nConvertFloatingLiteral() filename is NULL?\n"); + sloc = globalSRCMAN->getSpellingLoc(sloc); // should get spelling loc? + start = sloc.printToString(*globalSRCMAN); + filename = globalSRCMAN->getBufferName(sloc); + } + + unsigned int offset = globalSRCMAN->getFileOffset(sloc); + FILE *fp = fopen(filename, "r"); + fseek(fp, offset, SEEK_SET); // go to the part of the file where the float is defined + char buf[10240]; + fgets(buf, sizeof(buf), fp); // read a line starting where the float starts + fclose(fp); + // buf has the line we want grab the float constant out of it + char *ptr = buf; + if (*ptr == '-') ptr++; // ignore possible minus sign + int len = strspn(ptr, ".-0123456789f"); + buf[len] = '\0'; + chillAST_FloatingLiteral *chillFL = new chillAST_FloatingLiteral(val,1, buf); + NL_RET(chillFL); +} + + +chillAST_NodeList* ConvertImplicitCastExpr(ImplicitCastExpr *clangICE) { + chillAST_Node *sub = unwrap(ConvertGenericClangAST(clangICE->getSubExpr())); + chillAST_ImplicitCastExpr *chillICE = new chillAST_ImplicitCastExpr(sub); + + NL_RET(chillICE); +} + + +chillAST_NodeList* ConvertCStyleCastExpr(CStyleCastExpr *clangCSCE) { + const char *towhat = strdup(clangCSCE->getTypeAsWritten().getAsString().c_str()); + + chillAST_Node *sub = unwrap(ConvertGenericClangAST(clangCSCE->getSubExprAsWritten())); + chillAST_CStyleCastExpr *chillCSCE = new chillAST_CStyleCastExpr(towhat, sub); + NL_RET(chillCSCE); +} + + +chillAST_NodeList* ConvertReturnStmt(ReturnStmt *clangRS) { + chillAST_Node *retval = unwrap(ConvertGenericClangAST(clangRS->getRetValue())); // NULL is handled + + chillAST_ReturnStmt *chillRS = new chillAST_ReturnStmt(retval); + NL_RET(chillRS); +} + + +chillAST_NodeList* ConvertCallExpr(CallExpr *clangCE) { + chillAST_Node *callee = unwrap(ConvertGenericClangAST(clangCE->getCallee())); + chillAST_CallExpr *chillCE = new chillAST_CallExpr(callee); + int numargs = clangCE->getNumArgs(); + Expr **clangargs = clangCE->getArgs(); + for (int i = 0; i < numargs; i++) + chillCE->addArg(unwrap(ConvertGenericClangAST(clangargs[i]))); + + NL_RET(chillCE); +} + + +chillAST_NodeList* ConvertParenExpr(ParenExpr *clangPE) { + chillAST_Node *sub = unwrap(ConvertGenericClangAST(clangPE->getSubExpr())); + chillAST_ParenExpr *chillPE = new chillAST_ParenExpr(sub); + + NL_RET(chillPE); +} + + +chillAST_NodeList* ConvertTranslationUnit(TranslationUnitDecl *TUD, char *filename) { + static DeclContext *DC = TUD->castToDeclContext(TUD); + + chillAST_SourceFile *topnode = new chillAST_SourceFile(filename); + topnode->setFrontend("clang"); + topnode->chill_array_counter = 1; + topnode->chill_scalar_counter = 0; + + // now recursively build clang AST from the children of TUD + DeclContext::decl_iterator start = DC->decls_begin(); + DeclContext::decl_iterator end = DC->decls_end(); + for (DeclContext::decl_iterator DI = start; DI != end; ++DI) { + Decl *D = *DI; + chillAST_Node *child; + // Skip internal declarations of clang + + if (isa(D)) { + child = unwrap(ConvertFunctionDecl(dyn_cast(D))); + } else if (isa(D)) { + child = unwrap(ConvertVarDecl(dyn_cast(D))); + } else if (isa(D)) { + child = unwrap(ConvertTypeDefDecl(dyn_cast(D))); + } else if (isa(D)) { + CHILL_DEBUG_PRINT("\nTUD RecordDecl\n"); + child = unwrap(ConvertRecordDecl(dyn_cast(D))); + } else if (isa(D)) { + CHILL_ERROR("TUD TypeAliasDecl TODO \n"); + exit(-1); + } else { + CHILL_ERROR("\nTUD a declaration of type %s (%d) which I can't handle\n", D->getDeclKindName(), D->getKind()); + exit(-1); + } + topnode -> addChild(child); + + if (D->isImplicit() || !globalSRCMAN->getFilename(D->getLocation()).equals(filename)) child->isFromSourceFile = false; + } + + NL_RET(topnode); +} + +chillAST_NodeList* ConvertMemberExpr(clang::MemberExpr *clangME) { + chillAST_Node *base = unwrap(ConvertGenericClangAST(clangME->getBase())); + + DeclarationNameInfo memnameinfo = clangME->getMemberNameInfo(); + DeclarationName DN = memnameinfo.getName(); + const char *member = DN.getAsString().c_str(); + + chillAST_MemberExpr *ME = new chillAST_MemberExpr(base, member, clangME); + + NL_RET(ME); + +} + +chillAST_NodeList* ConvertGenericClangAST(Stmt *s) { + + if (s == NULL) return NULL; + Decl *D = (Decl *) s; + + chillAST_NodeList *ret = NULL; // find the SINGLE constant or data reference at this node or below + + if (isa(s)) { + ret = ConvertCompoundStmt(dyn_cast(s)); + } else if (isa(s)) { + ret = ConvertDeclStmt(dyn_cast(s)); + } else if (isa(s)) { + ret = ConvertForStmt(dyn_cast(s)); + } else if (isa(s)) { + ret = ConvertBinaryOperator(dyn_cast(s)); + } else if (isa(s)) { + ret = ConvertArraySubscriptExpr(dyn_cast(s)); + } else if (isa(s)) { + ret = ConvertDeclRefExpr(dyn_cast(s)); + } else if (isa(s)) { + ret = ConvertFloatingLiteral(dyn_cast(s)); + } else if (isa(s)) { + ret = ConvertIntegerLiteral(dyn_cast(s)); + } else if (isa(s)) { + ret = ConvertUnaryOperator(dyn_cast(s)); + } else if (isa(s)) { + ret = ConvertImplicitCastExpr(dyn_cast(s)); + } else if (isa(s)) { + ret = ConvertCStyleCastExpr(dyn_cast(s)); + } else if (isa(s)) { + ret = ConvertReturnStmt(dyn_cast(s)); + } else if (isa(s)) { + ret = ConvertCallExpr(dyn_cast(s)); + } else if (isa(s)) { + ret = ConvertParenExpr(dyn_cast(s)); + } else if (isa(s)) { + ret = ConvertIfStmt(dyn_cast(s)); + } else if (isa(s)) { + ret = ConvertMemberExpr(dyn_cast(s)); + } else if (isa(D)) { + ret = ConvertFunctionDecl( dyn_cast(D)); + } else if (isa(D)) { + ret = ConvertVarDecl( dyn_cast(D) ); + } else if (isa(D)) { + ret = ConvertTypeDefDecl( dyn_cast(D)); + } else { + // more work to do + if (isa(D)) CHILL_ERROR("Decl of kind %s unhandled\n", D->getDeclKindName() ); + if (isa(s)) CHILL_ERROR("Stmt of type %s unhandled\n", s->getStmtClassName()); + exit(-1); + } + + return ret; +} + +class NULLASTConsumer : public ASTConsumer { +}; + +aClangCompiler::aClangCompiler(char *filename) { + SourceFileName = strdup(filename); + + // Arguments to pass to the clang frontend + std::vector args; + args.push_back(strdup(filename)); + + // The compiler invocation needs a DiagnosticsEngine so it can report problems + diagnosticOptions = new DiagnosticOptions(); // private member of aClangCompiler + + pTextDiagnosticPrinter = new clang::TextDiagnosticPrinter(llvm::errs(), + diagnosticOptions); // private member of aClangCompiler + diagnosticsEngine = new clang::DiagnosticsEngine(diagID, diagnosticOptions, pTextDiagnosticPrinter); + + // Create the compiler invocation + // This class is designed to represent an abstract "invocation" of the compiler, + // including data such as the include paths, the code generation options, + // the warning flags, and so on. + std::unique_ptr CI(new clang::CompilerInvocation()); + clang::CompilerInvocation::CreateFromArgs(*CI, &args[0], &args[0] + args.size(), *diagnosticsEngine); + // Create the compiler instance + Clang = new clang::CompilerInstance(); // TODO should have a better name ClangCompilerInstance + + + // Get ready to report problems + Clang->createDiagnostics(nullptr, true); + //Clang.createDiagnostics(0, 0); + + + targetOptions = std::make_shared(); + targetOptions->Triple = llvm::sys::getDefaultTargetTriple(); + + TargetInfo *pti = TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), targetOptions); + + Clang->setTarget(pti); + Clang->createFileManager(); + FileManager &FileMgr = Clang->getFileManager(); + fileManager = &FileMgr; + Clang->createSourceManager(FileMgr); + SourceManager &SourceMgr = Clang->getSourceManager(); + sourceManager = &SourceMgr; // ?? aclangcompiler copy + globalSRCMAN = &SourceMgr; // TODO global bad + + Clang->setInvocation(CI.get()); // Replace the current invocation + + Clang->createPreprocessor(TU_Complete); + + Clang->createASTContext(); // needs preprocessor + astContext_ = &Clang->getASTContext(); + const FileEntry *FileIn = FileMgr.getFile(filename); // needs preprocessor + SourceMgr.setMainFileID(SourceMgr.createFileID(FileIn, clang::SourceLocation(), clang::SrcMgr::C_User)); + Clang->getDiagnosticClient().BeginSourceFile(Clang->getLangOpts(), &Clang->getPreprocessor()); + + NULLASTConsumer TheConsumer; // must pass a consumer in to ParseAST(). This one does nothing + CHILL_DEBUG_PRINT("actually parsing file %s using clang\n", filename); + ParseAST(Clang->getPreprocessor(), &TheConsumer, Clang->getASTContext()); + // Translation Unit is contents of a file + TranslationUnitDecl *TUD = astContext_->getTranslationUnitDecl(); + // create another AST, very similar to the clang AST but not written by idiots + CHILL_DEBUG_PRINT("converting entire clang AST into chill AST (ir_clang.cc)\n"); + chillAST_Node *wholefile = unwrap(ConvertTranslationUnit(TUD, filename)); + entire_file_AST = (chillAST_SourceFile *) wholefile; + astContext_ = &Clang->getASTContext(); +} + +void findmanually(chillAST_Node *node, char *procname, std::vector &procs) { + + if (node->getType() == CHILLAST_NODE_FUNCTIONDECL) { + char *name = ((chillAST_FunctionDecl *) node)->functionName; + if (!strcmp(name, procname)) { + procs.push_back(node); + // quit recursing. probably not correct in some horrible case + return; + } + } + + + // this is where the children can be used effectively. + // we don't really care what kind of node we're at. We just check the node itself + // and then its children is needed. + + int numc = node->getNumChildren(); + + for (int i = 0; i < numc; i++) + findmanually(node->getChild(i), procname, procs); + return; +} + +chillAST_FunctionDecl *aClangCompiler::findprocedurebyname(char *procname) { + + std::vector procs; + findmanually(entire_file_AST, procname, procs); + + if (procs.size() == 0) { + CHILL_ERROR("could not find function named '%s' in AST from file %s\n", procname, SourceFileName); + exit(-1); + } + + if (procs.size() > 1) { + CHILL_ERROR("oddly, found %d functions named '%s' in AST from file %s\n", procs.size(), procname, SourceFileName); + CHILL_ERROR("I am unsure what to do\n"); + exit(-1); + } + + CHILL_DEBUG_PRINT("found the procedure named %s\n", procname); + return (chillAST_FunctionDecl *) procs[0]; + +} \ No newline at end of file diff --git a/src/ir_chill.cc b/src/ir_chill.cc new file mode 100755 index 0000000..0769385 --- /dev/null +++ b/src/ir_chill.cc @@ -0,0 +1,1432 @@ +/***************************************************************************** + Copyright (C) 2009-2010 University of Utah + All Rights Reserved. + +Purpose: +CHiLL's CLANG interface. +convert from CLANG AST to chill AST + +Notes: +Array supports mixed pointer and array type in a single declaration. + +History: +12/10/2010 LLVM/CLANG Interface created by Saurav Muralidharan. + *****************************************************************************/ + +#include +#include +#include "ir_chill.hh" +#include "loop.hh" +#include "chill_error.hh" + +#include "clang/Frontend/FrontendActions.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "code_gen/CG_chillRepr.h" +#include "code_gen/CG_chillBuilder.h" +#include +#include + +#include "chillAST.h" + + +std::vector VariableDeclarations; +std::vector FunctionDeclarations; + +using namespace clang; +using namespace clang::driver; +using namespace omega; +using namespace std; + + + + +// ---------------------------------------------------------------------------- +// Class: IR_chillScalarSymbol +// ---------------------------------------------------------------------------- + +std::string IR_chillScalarSymbol::name() const { + return std::string(chillvd->varname); // CHILL +} + + +// Return size in bytes +int IR_chillScalarSymbol::size() const { + CHILL_DEBUG_PRINT("IR_chillScalarSymbol::size() probably WRONG\n"); + return (8); // bytes?? +} + + +bool IR_chillScalarSymbol::operator==(const IR_Symbol &that) const { + if (typeid(*this) != typeid(that)) + return false; + + const IR_chillScalarSymbol *l_that = static_cast(&that); + return this->chillvd == l_that->chillvd; +} + +IR_Symbol *IR_chillScalarSymbol::clone() const { + return new IR_chillScalarSymbol(ir_, chillvd); // clone +} + +// ---------------------------------------------------------------------------- +// Class: IR_chillArraySymbol +// ---------------------------------------------------------------------------- + +std::string IR_chillArraySymbol::name() const { + return std::string(strdup(chillvd->varname)); +} + + +int IR_chillArraySymbol::elem_size() const { + fprintf(stderr, "IR_chillArraySymbol::elem_size() TODO\n"); + exit(-1); + return 8; // TODO + //const ArrayType *at = dyn_cast(vd_->getType()); + //if(at) { + // return (vd_->getASTContext().getTypeSize(at->getElementType())) / 8; + //} else + // throw chill::error::ir("Symbol is not an array!"); + //return 0; +} + + +int IR_chillArraySymbol::n_dim() const { + return chillvd->numdimensions; +} + + +// TODO +omega::CG_outputRepr *IR_chillArraySymbol::size(int dim) const { + CHILL_ERROR("IR_chillArraySymbol::n_size() TODO \n"); + exit(-1); + return NULL; +} + + +bool IR_chillArraySymbol::operator!=(const IR_Symbol &that) const { + return chillvd != ((IR_chillArraySymbol *) &that)->chillvd; +} + +bool IR_chillArraySymbol::operator==(const IR_Symbol &that) const { + return chillvd == ((IR_chillArraySymbol *) &that)->chillvd; +} + + +IR_Symbol *IR_chillArraySymbol::clone() const { + return new IR_chillArraySymbol(ir_, chillvd, offset_); +} + +// ---------------------------------------------------------------------------- +// Class: IR_chillConstantRef +// ---------------------------------------------------------------------------- + +bool IR_chillConstantRef::operator==(const IR_Ref &that) const { + if (typeid(*this) != typeid(that)) + return false; + + const IR_chillConstantRef *l_that = static_cast(&that); + + if (this->type_ != l_that->type_) + return false; + + if (this->type_ == IR_CONSTANT_INT) + return this->i_ == l_that->i_; + else + return this->f_ == l_that->f_; +} + + +omega::CG_outputRepr *IR_chillConstantRef::convert() { + //assert(astContext_ != NULL); + if (type_ == IR_CONSTANT_INT) { + + fprintf(stderr, "IR_chillConstantRef::convert() unimplemented\n"); + exit(-1); + + // TODO + /* + BuiltinType *bint = new BuiltinType(BuiltinType::Int); + IntegerLiteral *ilit = new (astContext_)IntegerLiteral(*astContext_, llvm::APInt(32, i_), bint->desugar(), SourceLocation()); + omega::CG_chillRepr *result = new omega::CG_chillRepr(ilit); + delete this; + return result; + */ + } else + throw chill::error::ir("constant type not supported"); +} + + +IR_Ref *IR_chillConstantRef::clone() const { + if (type_ == IR_CONSTANT_INT) + return new IR_chillConstantRef(ir_, i_); + else if (type_ == IR_CONSTANT_FLOAT) + return new IR_chillConstantRef(ir_, f_); + else + throw chill::error::ir("constant type not supported"); +} + +// ---------------------------------------------------------------------------- +// Class: IR_chillScalarRef +// ---------------------------------------------------------------------------- + +bool IR_chillScalarRef::is_write() const { + return op_pos_ == OP_DEST; // 2 other alternatives: OP_UNKNOWN, OP_SRC +} + + +IR_ScalarSymbol *IR_chillScalarRef::symbol() const { + chillAST_VarDecl *vd = NULL; + if (chillvd) vd = chillvd; + return new IR_chillScalarSymbol(ir_, vd); +} + + +bool IR_chillScalarRef::operator==(const IR_Ref &that) const { + if (typeid(*this) != typeid(that)) + return false; + + const IR_chillScalarRef *l_that = static_cast(&that); + + return this->chillvd == l_that->chillvd; +} + + +omega::CG_outputRepr *IR_chillScalarRef::convert() { + if (!dre) CHILL_ERROR("IR_chillScalarRef::convert() CLANG SCALAR REF has no dre\n"); + omega::CG_chillRepr *result = new omega::CG_chillRepr(dre); + delete this; + return result; +} + +IR_Ref *IR_chillScalarRef::clone() const { + if (dre) return new IR_chillScalarRef(ir_, dre); + return new IR_chillScalarRef(ir_, chillvd); +} + + +// ---------------------------------------------------------------------------- +// Class: IR_chillArrayRef +// ---------------------------------------------------------------------------- + +bool IR_chillArrayRef::is_write() const { + return (iswrite); // TODO +} + + +// TODO +omega::CG_outputRepr *IR_chillArrayRef::index(int dim) const { + return new omega::CG_chillRepr(chillASE->getIndex(dim)); +} + + +IR_ArraySymbol *IR_chillArrayRef::symbol() const { + chillAST_Node *mb = chillASE->multibase(); + chillAST_VarDecl *vd = (chillAST_VarDecl *) mb; + IR_ArraySymbol *AS = new IR_chillArraySymbol(ir_, vd); + return AS; +/* + chillAST_Node *b = chillASE->base; + fprintf(stderr, "base of type %s\n", b->getTypeString()); + //b->print(); printf("\n"); fflush(stdout); + if (b->getType() == CHILLAST_NODE_IMPLICITCASTEXPR) { + b = ((chillAST_ImplicitCastExpr*)b)->subexpr; + fprintf(stderr, "base of type %s\n", b->getTypeString()); + } + + if (b->getType() == CHILLAST_NODE_DECLREFEXPR) { + if (NULL == ((chillAST_DeclRefExpr*)b)->decl) { + fprintf(stderr, "IR_chillArrayRef::symbol() var decl = 0x%x\n", ((chillAST_DeclRefExpr*)b)->decl); + exit(-1); + } + return new IR_chillArraySymbol(ir_, ((chillAST_DeclRefExpr*)b)->decl); // -> decl? + } + if (b->getType() == CHILLAST_NODE_ARRAYSUBSCRIPTEXPR) { // multidimensional array + return ( + } + fprintf(stderr, "IR_chillArrayRef::symbol() can't handle\n"); + fprintf(stderr, "base of type %s\n", b->getTypeString()); + exit(-1); + return NULL; +*/ +} + + +bool IR_chillArrayRef::operator!=(const IR_Ref &that) const { + bool op = (*this) == that; // opposite + return !op; +} + +bool IR_chillArrayRef::operator==(const IR_Ref &that) const { + const IR_chillArrayRef *l_that = static_cast(&that); + const chillAST_ArraySubscriptExpr *thatASE = l_that->chillASE; + return (*chillASE) == (*thatASE); + /* + + if (typeid(*this) != typeid(that)) + return false; + + const IR_chillArrayRef *l_that = static_cast(&that); + + return this->as_ == l_that->as_; + */ +} + + +omega::CG_outputRepr *IR_chillArrayRef::convert() { + CG_chillRepr *result = new CG_chillRepr(chillASE->clone()); +// omega::CG_chillRepr *temp = new omega::CG_chillRepr(static_cast(this->as_)); +// omega::CG_outputRepr *result = temp->clone(); + delete this; + return result; +} + + +IR_Ref *IR_chillArrayRef::clone() const { + return new IR_chillArrayRef(ir_, chillASE, iswrite); +} + + +// ---------------------------------------------------------------------------- +// Class: IR_chillLoop +// ---------------------------------------------------------------------------- +IR_chillLoop::IR_chillLoop(const IR_Code *ir, clang::ForStmt *tf) { + CHILL_ERROR("you lose\n"); + exit(-1); +}; + +IR_chillLoop::IR_chillLoop(const IR_Code *ir, chillAST_ForStmt *achillforstmt) { + CHILL_DEBUG_BEGIN + fprintf(stderr, "loop is:\n"); + achillforstmt->print(); + CHILL_DEBUG_END + + ir_ = ir; + chillforstmt = achillforstmt; + + chillAST_BinaryOperator *init = (chillAST_BinaryOperator *) chillforstmt->getInit(); + chillAST_BinaryOperator *cond = (chillAST_BinaryOperator *) chillforstmt->getCond(); + // check to be sure (assert) + if (!init->isAssignmentOp() || !cond->isComparisonOp()) { + CHILL_ERROR("malformed loop init or cond:\n"); + achillforstmt->print(); + exit(-1); + } + + chilllowerbound = init->getRHS(); + chillupperbound = cond->getRHS(); + conditionoperator = achillforstmt->conditionoperator; + + chillAST_Node *inc = chillforstmt->getInc(); + // check the increment + if (inc->getType() == CHILLAST_NODE_UNARYOPERATOR) { + if (!strcmp(((chillAST_UnaryOperator *) inc)->op, "++")) step_size_ = 1; + else step_size_ = -1; + } else if (inc->getType() == CHILLAST_NODE_BINARYOPERATOR) { + int beets = false; // slang + chillAST_BinaryOperator *bop = (chillAST_BinaryOperator *) inc; + if (bop->isAssignmentOp()) { // I=I+1 or similar + chillAST_Node *rhs = bop->getRHS(); // (I+1) + // TODO looks like this will fail for I=1+I or I=J+1 etc. do more checking + + char *assop = bop->getOp(); + if (!strcmp(assop, "+=") || !strcmp(assop, "-=")) { + chillAST_Node *stride = rhs; + //fprintf(stderr, "stride is of type %s\n", stride->getTypeString()); + if (stride->isIntegerLiteral()) { + int val = ((chillAST_IntegerLiteral *) stride)->value; + if (!strcmp(assop, "+=")) step_size_ = val; + else if (!strcmp(assop, "-=")) step_size_ = -val; + else beets = true; + } else beets = true; // += or -= but not constant stride + } else if (rhs->isBinaryOperator()) { + chillAST_BinaryOperator *binoprhs = (chillAST_BinaryOperator *) rhs; + chillAST_Node *intlit = binoprhs->getRHS(); + if (intlit->isIntegerLiteral()) { + int val = ((chillAST_IntegerLiteral *) intlit)->value; + if (!strcmp(binoprhs->getOp(), "+")) step_size_ = val; + else if (!strcmp(binoprhs->getOp(), "-")) step_size_ = -val; + else beets = true; + } else beets = true; + } else beets = true; + } else beets = true; + + if (beets) { + CHILL_ERROR("malformed loop increment (or more likely unhandled case)\n"); + inc->print(); + exit(-1); + } + } // binary operator + else { + CHILL_ERROR("IR_chillLoop constructor, unhandled loop increment\n"); + inc->print(); + exit(-1); + } + //inc->print(0, stderr);fprintf(stderr, "\n"); + + chillAST_DeclRefExpr *dre = (chillAST_DeclRefExpr *) init->getLHS(); + if (!dre->isDeclRefExpr()) { + CHILL_DEBUG_PRINT("malformed loop init.\n"); + init->print(); + } + + chillindex = dre; // the loop index variable + + //fprintf(stderr, "\n\nindex is "); dre->print(0, stderr); fprintf(stderr, "\n"); + //fprintf(stderr, "init is "); + //chilllowerbound->print(0, stderr); fprintf(stderr, "\n"); + //fprintf(stderr, "condition is %s ", "<"); + //chillupperbound->print(0, stderr); fprintf(stderr, "\n"); + //fprintf(stderr, "step size is %d\n\n", step_size_) ; + + chillbody = achillforstmt->getBody(); + + CHILL_DEBUG_PRINT("IR_xxxxLoop::IR_xxxxLoop() DONE\n"); +} + + +omega::CG_outputRepr *IR_chillLoop::lower_bound() const { + CHILL_DEBUG_PRINT("IR_xxxxLoop::lower_bound()\n"); + return new omega::CG_chillRepr(chilllowerbound); +} + +omega::CG_outputRepr *IR_chillLoop::upper_bound() const { + CHILL_DEBUG_PRINT("IR_xxxxLoop::upper_bound()\n"); + return new omega::CG_chillRepr(chillupperbound); +} + +IR_Block *IR_chillLoop::body() const { + CHILL_DEBUG_PRINT("IR_xxxxLoop::body()\n"); + //assert(isa(tf_->getBody())); + //fprintf(stderr, "returning a clangBLOCK corresponding to the body of the loop\n"); + //fprintf(stderr, "body type %s\n", chillbody->getTypeString()); + return new IR_chillBlock(ir_, chillbody); // static_cast(tf_->getBody())); +} + +IR_Control *IR_chillLoop::clone() const { + CHILL_DEBUG_PRINT("IR_xxxxLoop::clone()\n"); + //chillforstmt->print(); fflush(stdout); + return new IR_chillLoop(ir_, chillforstmt); +} + +IR_CONDITION_TYPE IR_chillLoop::stop_cond() const { + chillAST_BinaryOperator *loopcondition = (chillAST_BinaryOperator *) chillupperbound; + CHILL_DEBUG_PRINT("IR_xxxxLoop::stop_cond()\n"); + return conditionoperator; +} + +IR_Block *IR_chillLoop::convert() { // convert the loop to a block + CHILL_DEBUG_PRINT("IR_xxxxLoop::convert() maybe \n"); + return new IR_chillBlock(ir_, chillbody); // ?? + return NULL; +} + +void IR_chillLoop::dump() const { + CHILL_ERROR("TODO: IR_chillLoop::dump()\n"); + exit(-1); +} + + +// ---------------------------------------------------------------------------- +// Class: IR_chillBlock +// ---------------------------------------------------------------------------- +omega::CG_outputRepr *IR_chillBlock::original() const { + CHILL_ERROR("IR_xxxxBlock::original() TODO \n"); + exit(-1); + return NULL; +} + + +omega::CG_outputRepr *IR_chillBlock::extract() const { + // if the block refers to a compound statement, return the next level + // of statements ; otherwise just return a repr of the statements + omega::CG_chillRepr *OR; + CHILL_DEBUG_PRINT("adding a statement from IR_chillBlock::extract()\n"); + OR = new omega::CG_chillRepr(); // empty of statements + for (int i = 0; i < statements.size(); i++) OR->addStatement(statements[i]); + CHILL_DEBUG_PRINT("IR_xxxxBlock::extract() LEAVING\n"); + return OR; +} + +IR_Control *IR_chillBlock::clone() const { + CHILL_DEBUG_PRINT("IR_xxxxBlock::clone()\n"); + return new IR_chillBlock(this); // shallow copy ? +} + +void IR_chillBlock::dump() const { + CHILL_DEBUG_PRINT("IR_chillBlock::dump() TODO\n"); + return; +} + +//StmtList +vector IR_chillBlock::getStmtList() const { + CHILL_DEBUG_PRINT("IR_xxxxBlock::getStmtList()\n"); + return statements; // ?? +} + + +void IR_chillBlock::addStatement(chillAST_Node *s) { + statements.push_back(s); +} + +// ---------------------------------------------------------------------------- +// Class: IR_clangCode_Global_Init +// ---------------------------------------------------------------------------- + +IR_clangCode_Global_Init *IR_clangCode_Global_Init::pinstance = 0; + + +IR_clangCode_Global_Init *IR_clangCode_Global_Init::Instance(char **argv) { + if (pinstance == 0) { + // this is the only way to create an IR_clangCode_Global_Init + pinstance = new IR_clangCode_Global_Init; + pinstance->ClangCompiler = new aClangCompiler(argv[1]); + + } + return pinstance; +} + +#ifdef NOPE +IR_clangCode_Global_Init::IR_clangCode_Global_Init(char *filename , clang::FileSystemOptions fso ) : + fileManager(fso) // , headerSearch( headerSearchOptions, fileManager, diagengine, languageOptions, pTargetInfo ) +{ + /* CLANG Initialization */ + diagnosticsEngine = new clang::DiagnosticsEngine( const IntrusiveRefCntPtr &Diags, + diagnosticOptionsnsa utah + ) ; // DiagnosticConsumer *client = 0, bool ShouldOwnClient = true) + pTextDiagnosticPrinter = new clang::TextDiagnosticPrinter(llvm::outs(), diagnosticOptions); + diagnostic = new clang::Diagnostic(pTextDiagnosticPrinter); + sourceManager = new clang::SourceManager(*diagnostic); + + // FIXME + + // -- Platform Specific Code lives here + // This depends on A) that you're running linux and + // B) that you have the same GCC LIBs installed that + // I do. + // Search through Clang itself for something like this, + // go on, you won't find it. The reason why is Clang + // has its own versions of std* which are installed under + // /usr/local/lib/clang//include/ + // See somewhere around Driver.cpp:77 to see Clang adding + // its version of the headers to its include path. + /*headerSearchOptions.AddPath("/usr/include/linux", clang::frontend::Angled, false, false, false); + headerSearchOptions.AddPath("/usr/include/c++/4.3/tr1", clang::frontend::Angled, false, false, false); + headerSearchOptions.AddPath("/usr/include/c++/4.3", clang::frontend::Angled, false, false, false);*/ + // -- End of Platform Specific Code + + targetOptions.Triple = llvm::sys::getHostTriple(); + pTargetInfo = clang::TargetInfo::CreateTargetInfo(*diagnostic, targetOptions); + clang::ApplyHeaderSearchOptions( headerSearch, headerSearchOptions, languageOptions, pTargetInfo->getTriple()); + preprocessor = new clang::Preprocessor(*diagnostic, languageOptions, *pTargetInfo, *sourceManager, headerSearch); + clang::InitializePreprocessor(*preprocessor, preprocessorOptions, headerSearchOptions, frontendOptions); + const clang::FileEntry *pFile = fileManager.getFile(filename); + sourceManager->createMainFileID(pFile); + //preprocessor.EnterMainSourceFile(); + + clang::TargetInfo &targetInfo = *pTargetInfo; + + idTable = new clang::IdentifierTable(languageOptions); + + builtinContext = new clang::Builtin::Context(targetInfo); + astContext_ = new clang::ASTContext(languageOptions, *sourceManager, targetInfo, *idTable, selTable, *builtinContext, 0); + astConsumer_ = new Chill_ASTConsumer(); + clang::Sema sema(*preprocessor, *astContext_, *astConsumer_); + sema.Initialize(); + clang::ParseAST(*preprocessor, astConsumer_, *astContext_); +} +#endif + + +IR_clangCode_Global_Init::~IR_clangCode_Global_Init() { + /* + delete pTextDiagnosticPrinter; + delete diagnostic; + delete sourceManager; + delete preprocessor; + delete idTable; + delete builtinContext; + delete astContext_; + delete astConsumer_; + */ +} + + + +// ---------------------------------------------------------------------------- +// Class: IR_clangCode +// ---------------------------------------------------------------------------- + +IR_clangCode::IR_clangCode(const char *filename, const char *proc_name, const char *dest_name) : IR_clangCode(filename, + proc_name) { + outfilename = strdup(dest_name); +} +IR_clangCode::IR_clangCode(const char *fname, const char *proc_name) : IR_Code() { + CHILL_DEBUG_PRINT("IR_xxxxCode::IR_xxxxCode()\n"); + //fprintf(stderr, "IR_clangCode::IR_clangCode( filename %s, procedure %s )\n", filename, proc_name); + + filename = strdup(fname); // filename is internal to IR_clangCode + procedurename = strdup(proc_name); + outfilename = NULL; + + int argc = 2; + char *argv[2]; + argv[0] = strdup("chill"); + argv[1] = strdup(filename); + + // use clang to parse the input file ? (or is that already done?) + //fprintf(stderr, "IR_clangCode::IR_clangCode(), parsing input file %s\n", argv[1]); + + // this causes opening and parsing of the file. + // this is the only call to Instance that has an argument list or file name + IR_clangCode_Global_Init *pInstance = IR_clangCode_Global_Init::Instance(argv); + + if (pInstance) { + + aClangCompiler *Clang = pInstance->ClangCompiler; + //fprintf(stderr, "Clang is 0x%x\n", Clang); + + //fprintf(stderr, "want to get pointer to clang ast for procedure %s\n", proc_name); + pInstance->setCurrentFunction(NULL); // we have no function AST yet + + entire_file_AST = Clang->entire_file_AST; // ugly that same name, different classes + chillAST_FunctionDecl *localFD = Clang->findprocedurebyname(strdup(proc_name)); // stored locally + //fprintf(stderr, "back from findprocedurebyname( %s )\n", proc_name ); + //localFD->print(); + + pInstance->setCurrentFunction(localFD); + + CHILL_DEBUG_BEGIN + fprintf(stderr, "Dumping AST for localFD\n"); + localFD->dump(); + CHILL_DEBUG_END + + CHILL_DEBUG_PRINT("calling new CG_chillBuilder() umwut?\n"); + ocg_ = new omega::CG_chillBuilder(localFD->getSourceFile(),localFD); // ocg == omega code gen + chillfunc = localFD; + + } + + CHILL_DEBUG_PRINT("returning after reading source file and finding function\n\n"); + + //chillfunc->dump( 0, stderr); + +} + + +IR_clangCode::~IR_clangCode() { + CHILL_DEBUG_PRINT("output happening as part of the destructor !!\n"); + + chillfunc->constantFold(); + + chillfunc->cleanUpVarDecls(); + + // TODO should output the entire file, not just the function we're working on + chillAST_SourceFile *src = chillfunc->getSourceFile(); + if (src) { + CHILL_DEBUG_BEGIN + src->dump(); + CHILL_DEBUG_END + if (src->isSourceFile()) src->printToFile(outfilename); + } +} + + +//TODO +IR_ScalarSymbol *IR_clangCode::CreateScalarSymbol(const IR_Symbol *sym, int i) { + if (typeid(*sym) == typeid(IR_chillScalarSymbol)) { // should be the case ??? + fprintf(stderr, "IR_xxxxCode::CreateScalarSymbol() from a scalar symbol\n"); + const IR_chillScalarSymbol *CSS = (IR_chillScalarSymbol *) sym; + chillAST_VarDecl *vd = CSS->chillvd; + + // do we have to check to see if it's already there? + VariableDeclarations.push_back(vd); + chillAST_Node *bod = chillfunc->getBody(); // always a compoundStmt ?? + bod->insertChild(0, vd); + fprintf(stderr, "returning ... really\n"); + return new IR_chillScalarSymbol(this, CSS->chillvd); // CSS->clone(); + } + + if (typeid(*sym) == typeid(IR_chillArraySymbol)) { + fprintf(stderr, "IR_xxxxCode::CreateScalarSymbol() from an array symbol?\n"); + const IR_chillArraySymbol *CAS = (IR_chillArraySymbol *) sym; + + chillAST_VarDecl *vd = CAS->chillvd; + fflush(stdout); + + // figure out the base type (probably float) of the array + char *basetype = vd->underlyingtype; + fprintf(stderr, "scalar will be of type SgType%s\n", basetype); + + char tmpname[128]; + sprintf(tmpname, "newVariable%i\0", vd->chill_scalar_counter++); + chillAST_VarDecl *scalarvd = new chillAST_VarDecl(basetype, tmpname, "", NULL); // TODO parent + scalarvd->print(); + printf("\n"); + fflush(stdout); + + fprintf(stderr, "VarDecl has parent that is a NULL\n"); + + return (IR_ScalarSymbol *) (new IR_chillScalarSymbol(this, scalarvd)); // CSS->clone(); + } + + fprintf(stderr, + "IR_clangCode::CreateScalarSymbol(), passed a sym that is not a clang scalar symbol OR an array symbol???\n"); + int *n = NULL; + n[0] = 1; + exit(-1); + return NULL; +} + + +IR_ArraySymbol * +IR_clangCode::CreateArraySymbol(const IR_Symbol *sym, std::vector &size, int i) { + fprintf(stderr, "IR_xxxxCode::CreateArraySymbol()\n"); + + // build a new array name + char namestring[128]; + + sprintf(namestring, "_P%d\0", entire_file_AST->chill_array_counter++); + fprintf(stderr, "creating Array %s\n", namestring); + + char arraypart[100]; + char *s = &arraypart[0]; + + for (int i = 0; i < size.size(); i++) { + omega::CG_outputRepr *OR = size[i]; + CG_chillRepr *CR = (CG_chillRepr *) OR; + //fprintf(stderr, "%d chillnodes\n", CR->chillnodes.size()); + + // this SHOULD be 1 chillnode of type IntegerLiteral (per dimension) + int numnodes = CR->chillnodes.size(); + if (1 != numnodes) { + fprintf(stderr, + "IR_clangCode::CreateArraySymbol() array dimension %d has %d chillnodes\n", + i, numnodes); + exit(-1); + } + + chillAST_Node *nodezero = CR->chillnodes[0]; + if (!nodezero->isIntegerLiteral()) { + fprintf(stderr, "IR_clangCode::CreateArraySymbol() array dimension %d not an IntegerLiteral\n", i); + exit(-1); + } + + chillAST_IntegerLiteral *IL = (chillAST_IntegerLiteral *) nodezero; + int val = IL->value; + sprintf(s, "[%d]\0", val); + s = &arraypart[strlen(arraypart)]; + } + //fprintf(stderr, "arraypart '%s'\n", arraypart); + + chillAST_VarDecl *vd = new chillAST_VarDecl("float", namestring, arraypart, NULL); // todo type from sym + + // put decl in some symbol table + VariableDeclarations.push_back(vd); + // insert decl in the IR_code body + chillAST_Node *bod = chillfunc->getBody(); // always a compoundStmt ?? + bod->insertChild(0, vd); + + return new IR_chillArraySymbol(this, vd); +} + +// TODO +std::vector IR_clangCode::FindScalarRef(const omega::CG_outputRepr *repr) const { + std::vector scalars; + + const omega::CG_chillRepr *crepr = static_cast(repr); + std::vector chillstmts = crepr->getChillCode(); + + std::vector refs; + for (int i = 0; i < chillstmts.size(); i++) { + chillstmts[i]->gatherScalarRefs(refs,false); + } + for (int i = 0; i < refs.size(); i++) { + scalars.push_back(new IR_chillScalarRef(this, refs[i])); + } + return scalars; +} + + +IR_ScalarRef *IR_clangCode::CreateScalarRef(const IR_ScalarSymbol *sym) { + IR_chillScalarRef *sr = new IR_chillScalarRef(this, new chillAST_DeclRefExpr( + ((IR_chillScalarSymbol *) sym)->chillvd)); // uses VarDecl to mak a declrefexpr + return sr; +} + +bool IR_clangCode::FromSameStmt(IR_ArrayRef *A, IR_ArrayRef *B) { + return ((IR_chillArrayRef*)A)->chillASE->findContainingStmt() == ((IR_chillArrayRef*)A)->chillASE->findContainingStmt(); +} + +IR_ArrayRef *IR_clangCode::CreateArrayRef(const IR_ArraySymbol *sym, std::vector &index) { + fprintf(stderr, "IR_clangCode::CreateArrayRef() ir_clang.cc\n"); + fprintf(stderr, "sym->n_dim() %d index.size() %d\n", sym->n_dim(), index.size()); + + int t; + if (sym->n_dim() != index.size()) { + throw std::invalid_argument("incorrect array symbol dimensionality dim != size ir_clang.cc L2359"); + } + + const IR_chillArraySymbol *c_sym = static_cast(sym); + chillAST_VarDecl *vd = c_sym->chillvd; + std::vector inds; + + for (int i = 0; i < index.size(); i++) { + CG_chillRepr *CR = (CG_chillRepr *) index[i]; + + int numnodes = CR->chillnodes.size(); + if (1 != numnodes) { + CHILL_ERROR("IR_clangCode::CreateArrayRef() array dimension %d has %d chillnodes\n", i, numnodes); + exit(-1); + } + + inds.push_back(CR->chillnodes[0]); + + /* + chillAST_Node *nodezero = CR->chillnodes[0]; + if (!nodezero->isIntegerLiteral()) { + fprintf(stderr,"IR_clangCode::CreateArrayRef() array dimension %d not an IntegerLiteral\n",i); + fprintf(stderr, "it is a %s\n", nodezero->getTypeString()); + nodezero->print(); printf("\n"); fflush(stdout); + exit(-1); + } + + chillAST_IntegerLiteral *IL = (chillAST_IntegerLiteral *)nodezero; + int val = IL->value; + inds.push_back( val ); + */ + } + + // now we've got the vardecl AND the indeces to make a chillAST that represents the array reference + // TODO Passing NULL for chillAST node? + CHILL_DEBUG_PRINT("Passed NULL as chillAST node"); + chillAST_ArraySubscriptExpr *ASE = new chillAST_ArraySubscriptExpr(vd, inds); + + auto ref = new IR_chillArrayRef(this, ASE, 0); + + return ref; +} + +// find all array references ANYWHERE in this block of code ?? +std::vector IR_clangCode::FindArrayRef(const omega::CG_outputRepr *repr) const { + //fprintf(stderr, "FindArrayRef()\n"); + std::vector arrays; + const omega::CG_chillRepr *crepr = static_cast(repr); + std::vector chillstmts = crepr->getChillCode(); + + //fprintf(stderr, "there are %d chill statements in this repr\n", chillstmts.size()); + + std::vector refs; + for (int i = 0; i < chillstmts.size(); i++) { + //fprintf(stderr, "\nchillstatement %d = ", i); chillstmts[i]->print(0, stderr); fprintf(stderr, "\n"); + chillstmts[i]->gatherArrayRefs(refs, false); + } + //fprintf(stderr, "%d total refs\n", refs.size()); + for (int i = 0; i < refs.size(); i++) { + if (refs[i]->imreadfrom) { + //fprintf(stderr, "ref[%d] going to be put in TWICE, as both read and write\n", i); + arrays.push_back(new IR_chillArrayRef(this, refs[i], 0)); // UGLY TODO dual usage of a ref in "+=" + } + arrays.push_back(new IR_chillArrayRef(this, refs[i], refs[i]->imwrittento)); // this is wrong + // we need to know whether this reference will be written, etc. + } + + /* + if(chillstmts.size() > 1) { + for(int i=0; isize(); ++i) { + omega::CG_chillRepr *r = new omega::CG_chillRepr((*tnl)[i]); + std::vector a = FindArrayRef(r); + delete r; + std::copy(a.begin(), a.end(), back_inserter(arrays)); + } + } else if(chillstmts.size() == 1) { + Stmt *s = (*tnl)[0]; + + if(CompoundStmt *cs = dyn_cast(s)) { + for(CompoundStmt::body_iterator bi = cs->body_begin(); bi != cs->body_end(); ++bi) { + omega::CG_chillRepr *r = new omega::CG_chillRepr(*bi); + std::vector a = FindArrayRef(r); + delete r; + std::copy(a.begin(), a.end(), back_inserter(arrays)); + } + } else if(ForStmt *fs = dyn_cast(s)) { + omega::CG_chillRepr *r = new omega::CG_chillRepr(fs->getBody()); + std::vector a = FindArrayRef(r); + delete r; + std::copy(a.begin(), a.end(), back_inserter(arrays)); + } else if(IfStmt *ifs = dyn_cast(s)) { + omega::CG_chillRepr *r = new omega::CG_chillRepr(ifs->getCond()); + std::vector a = FindArrayRef(r); + delete r; + std::copy(a.begin(), a.end(), back_inserter(arrays)); + r = new omega::CG_chillRepr(ifs->getThen()); + a = FindArrayRef(r); + delete r; + std::copy(a.begin(), a.end(), back_inserter(arrays)); + if(Stmt *s_else = ifs->getElse()) { + r = new omega::CG_chillRepr(s_else); + a = FindArrayRef(r); + delete r; + std::copy(a.begin(), a.end(), back_inserter(arrays)); + } + } else if(Expr *e = dyn_cast(s)) { + omega::CG_chillRepr *r = new omega::CG_chillRepr(static_cast(s)); + std::vector a = FindArrayRef(r); + delete r; + std::copy(a.begin(), a.end(), back_inserter(arrays)); + } else throw chill::error::ir("control structure not supported"); + } + */ +/* + else { // We have an expression + Expr *op = static_cast(repr)->GetExpression(); + if(0) { // TODO: Handle pointer reference exp. here + } else if(BinaryOperator *bop = dyn_cast(op)) { + omega::CG_chillRepr *r1 = new omega::CG_chillRepr(bop->getLHS()); + std::vector a1 = FindArrayRef(r1); + delete r1; + std::copy(a1.begin(), a1.end(), back_inserter(arrays)); + omega::CG_chillRepr *r2 = new omega::CG_chillRepr(bop->getRHS()); + std::vector a2 = FindArrayRef(r2); + delete r2; + std::copy(a2.begin(), a2.end(), back_inserter(arrays)); + } else if(UnaryOperator *uop = dyn_cast(op)) { + omega::CG_chillRepr *r1 = new omega::CG_chillRepr(uop->getSubExpr()); + std::vector a1 = FindArrayRef(r1); + delete r1; + std::copy(a1.begin(), a1.end(), back_inserter(arrays)); + } //else throw chill::error::ir("Invalid expr. type passed to FindArrayRef"); + } + */ + return arrays; +} + + +std::vector IR_clangCode::FindOneLevelControlStructure(const IR_Block *block) const { + const IR_chillBlock *CB = (const IR_chillBlock *) block; + //fprintf(stderr, "block 0x%x\n", block); + + std::vector controls; + + chillAST_Node *blockast = NULL; + int numstmts = CB->statements.size(); + bool unwrap = false; + CHILL_DEBUG_PRINT("%d statements\n", numstmts); + + if (numstmts == 0) return controls; + + else if (numstmts == 1) blockast = CB->statements[0]; // a single statement + + CHILL_DEBUG_BEGIN + for (int i = 0; i < CB->statements.size(); ++i) { + fprintf(stderr, "block's AST is of type %s\n", CB->statements[i]->getTypeString()); + CB->statements[i]->print(); + } + CHILL_DEBUG_END + + // build up a vector of "controls". + // a run of straight-line code (statements that can't cause branching) will be + // bundled up into an IR_Block + // ifs and loops will get their own entry + const std::vector *children = NULL; + if (blockast) { + if (blockast->isFunctionDecl()) { + chillAST_FunctionDecl *FD = (chillAST_FunctionDecl *) blockast; + chillAST_Node *bod = FD->getBody(); + children = bod->getChildren(); + unwrap = true; + } + if (blockast->isCompoundStmt()) { + children = blockast->getChildren(); + unwrap = true; + } + if (blockast->isForStmt()) { + controls.push_back(new IR_chillLoop(this, (chillAST_ForStmt *) blockast)); + return controls; + } + } + if (!children) + children = &(CB->statements); + + int numchildren = children->size(); + int ns; + IR_chillBlock *basicblock = new IR_chillBlock(this); // no statements + for (int i = 0; i < numchildren; i++) { + CHILLAST_NODE_TYPE typ = (*children)[i]->getType(); + if (typ == CHILLAST_NODE_LOOP) { + ns = basicblock->numstatements(); + if (ns) { + CHILL_DEBUG_PRINT("pushing a run of statements as a block\n"); + controls.push_back(basicblock); + basicblock = new IR_chillBlock(this); // start a new one + } + + CHILL_DEBUG_PRINT("pushing the loop at %d\n", i); + controls.push_back(new IR_chillLoop(this, (chillAST_ForStmt *) (*children)[i])); + } else if (typ == CHILLAST_NODE_IFSTMT ) { + ns = basicblock->numstatements(); + if (ns) { + CHILL_DEBUG_PRINT("pushing a run of statements as a block\n"); + controls.push_back(basicblock); + basicblock = new IR_chillBlock(this); // start a new one + } + CHILL_DEBUG_PRINT("pushing the if at %d\n", i); + controls.push_back(new IR_chillIf(this, (chillAST_IfStmt *) (*children)[i])); + } else + basicblock->addStatement((*children)[i]); + } // for each child + ns = basicblock->numstatements(); + if (ns != 0 && (unwrap || ns != numchildren)) + controls.push_back(basicblock); + + CHILL_DEBUG_PRINT("returning vector of %d controls\n", controls.size()); + return controls; +} + + +IR_Block *IR_clangCode::MergeNeighboringControlStructures(const std::vector &controls) const { + CHILL_DEBUG_PRINT("%d controls\n", controls.size()); + + if (controls.size() == 0) + return NULL; + + IR_chillBlock *CBlock = new IR_chillBlock(controls[0]->ir_); // the thing we're building + + std::vector statements; + chillAST_Node *parent = NULL; + for (int i = 0; i < controls.size(); i++) { + switch (controls[i]->type()) { + case IR_CONTROL_LOOP: { + CHILL_DEBUG_PRINT("control %d is IR_CONTROL_LOOP\n", i); + chillAST_ForStmt *loop = static_cast(controls[i])->chillforstmt; + if (parent == NULL) { + parent = loop->getParent(); + } else { + if (parent != loop->getParent()) { + throw chill::error::ir("controls to merge not at the same level"); + } + } + CBlock->addStatement(loop); + break; + } + case IR_CONTROL_BLOCK: { + CHILL_DEBUG_PRINT("control %d is IR_CONTROL_BLOCK\n", i); + IR_chillBlock *CB = static_cast(controls[i]); + std::vector blockstmts = CB->statements; + for (int j = 0; j < blockstmts.size(); j++) { + if (parent == NULL) { + parent = blockstmts[j]->getParent(); + } else { + if (parent != blockstmts[j]->getParent()) { + throw chill::error::ir( + "ir_clang.cc IR_clangCode::MergeNeighboringControlStructures controls to merge not at the same level"); + } + } + CBlock->addStatement(blockstmts[j]); + } + break; + } + default: + throw chill::error::ir("unrecognized control to merge"); + } + } // for each control + + return CBlock; +} + + +IR_Block *IR_clangCode::GetCode() const { // return IR_Block corresponding to current function? + //fprintf(stderr, "IR_clangCode::GetCode()\n"); + //Stmt *s = func_->getBody(); // clang statement, and clang getBody + //fprintf(stderr, "chillfunc 0x%x\n", chillfunc); + + //chillAST_Node *bod = chillfunc->getBody(); // chillAST + //fprintf(stderr, "printing the function getBody()\n"); + //fprintf(stderr, "sourceManager 0x%x\n", sourceManager); + //bod->print(); + + return new IR_chillBlock(this, chillfunc); +} + + +void IR_clangCode::ReplaceCode(IR_Control *old, omega::CG_outputRepr *repr) { + CG_chillRepr *chillrepr = (CG_chillRepr *) repr; + std::vector newcode = chillrepr->getChillCode(); + int numnew = newcode.size(); + struct IR_chillLoop *cloop; + std::vector olddecls; + chillfunc->gatherVarDecls(olddecls); + std::vector decls; + for (int i = 0; i < numnew; i++) + newcode[i]->gatherVarUsage(decls); + + for (int i = 0; i < decls.size(); i++) { + int inthere = 0; + for (int j = 0; j < VariableDeclarations.size(); j++) + if (VariableDeclarations[j] == decls[i]) + inthere = 1; + for (int j = 0; j < olddecls.size(); j++) { + if (decls[i] == olddecls[j]) + inthere = 1; + if (!strcmp(decls[i]->varname, olddecls[j]->varname)) + if (!strcmp(decls[i]->arraypart, olddecls[j]->arraypart)) + inthere = 1; + } + if (!inthere) { + chillfunc->getBody()->insertChild(0, decls[i]); + olddecls.push_back(decls[i]); + } + } + + chillAST_Node *par; + switch (old->type()) { + case IR_CONTROL_LOOP: { + cloop = (struct IR_chillLoop *) old; + chillAST_ForStmt *forstmt = cloop->chillforstmt; + + par = forstmt->getParent(); + if (!par) { + CHILL_ERROR("old parent was NULL\n"); + CHILL_ERROR("ir_clang.cc that will not work very well.\n"); + exit(-1); + } + + CHILL_DEBUG_BEGIN + fprintf(stderr, "\nold parent was\n\n{\n"); + par->print(); + fprintf(stderr, "\n}\n"); + CHILL_DEBUG_END + + std::vector *oldparentcode = par->getChildren(); // probably only works for compoundstmts + + // find loop in the parent + int numstatements = oldparentcode->size(); + int index = par->findChild(forstmt); + if (index < 0) { + CHILL_ERROR("can't find the loop in its parent\n"); + exit(-1); + } + // insert the new code + par->setChild(index, newcode[0]); // overwrite old stmt + // do we need to update the IR_cloop? + cloop->chillforstmt = (chillAST_ForStmt *) newcode[0]; // ?? DFL + + if (numnew > 1) { + // add the rest of the new statements + CHILL_DEBUG_BEGIN + for (int i = 1; i < numnew; i++) { + fprintf(stderr, "inserting \n"); + newcode[i]->print(0, stderr); + } + CHILL_DEBUG_END + for (int i = 1; i < numnew; i++) + par->insertChild(index + i, newcode[i]); // sets parent + } + + // TODO add in (insert) variable declarations that go with the new loops + + fflush(stdout); + } + break; + case IR_CONTROL_BLOCK: { + CHILL_ERROR("old is IR_CONTROL_BLOCK\n"); + par = ((IR_chillBlock*)old)->statements[0]->getParent(); + if (!par) { + CHILL_ERROR("old parent was NULL\n"); + CHILL_ERROR("ir_clang.cc that will not work very well.\n"); + exit(-1); + } + IR_chillBlock *cblock = (struct IR_chillBlock *) old; + std::vector *oldparentcode = par->getChildren(); // probably only works for compoundstmts + int index = par->findChild(cblock->statements[0]); + for (int i = 0;inumstatements();++i) // delete all current statements + par->removeChild(par->findChild(cblock->statements[i])); + for (int i = 0; i < numnew; i++) + par->insertChild(index + i, newcode[i]); // insert New child + // TODO add in (insert) variable declarations that go with the new loops + break; + } + default: + throw chill::error::ir("control structure to be replaced not supported"); + break; + } + + fflush(stdout); + CHILL_DEBUG_BEGIN + fprintf(stderr, "new parent2 is\n\n{\n"); + std::vector *newparentcode = par->getChildren(); + for (int i = 0; i < newparentcode->size(); i++) { + (*newparentcode)[i]->print(); + } + fprintf(stderr, "}\n"); + CHILL_DEBUG_END + + +} + + +void IR_clangCode::ReplaceExpression(IR_Ref *old, omega::CG_outputRepr *repr) { + if (typeid(*old) == typeid(IR_chillArrayRef)) { + IR_chillArrayRef *CAR = (IR_chillArrayRef *) old; + chillAST_ArraySubscriptExpr *CASE = CAR->chillASE; + + omega::CG_chillRepr *crepr = (omega::CG_chillRepr *) repr; + if (crepr->chillnodes.size() != 1) { + CHILL_ERROR("IR_clangCode::ReplaceExpression(), replacing with %d chillnodes???\n"); + //exit(-1); + } + + chillAST_Node *newthing = crepr->chillnodes[0]; + + if (!CASE->getParent()) { + CHILL_ERROR("IR_clangCode::ReplaceExpression() old has no parent ??\n"); + exit(-1); + } + + CASE->getParent()->replaceChild(CASE, newthing); + + } else if (typeid(*old) == typeid(IR_chillScalarRef)) { + fprintf(stderr, "IR_clangCode::ReplaceExpression() IR_chillScalarRef unhandled\n"); + } else { + fprintf(stderr, "UNKNOWN KIND OF REF\n"); + exit(-1); + } + + delete old; +} + + +// TODO +IR_CONDITION_TYPE IR_clangCode::QueryBooleanExpOperation(const omega::CG_outputRepr *repr) const { + return IR_COND_UNKNOWN; +} + + +IR_OPERATION_TYPE IR_clangCode::QueryExpOperation(const omega::CG_outputRepr *repr) const { + CG_chillRepr *crepr = (CG_chillRepr *) repr; + chillAST_Node *node = crepr->chillnodes[0]; + // really need to be more rigorous than this hack // TODO + if (node->isImplicitCastExpr()) node = ((chillAST_ImplicitCastExpr *) node)->getSubExpr(); + if (node->isCStyleCastExpr()) node = ((chillAST_CStyleCastExpr *) node)->getSubExpr(); + if (node->isParenExpr()) node = ((chillAST_ParenExpr *) node)->getSubExpr(); + + if (node->isIntegerLiteral() || node->isFloatingLiteral()) return IR_OP_CONSTANT; + else if (node->isBinaryOperator() || node->isUnaryOperator()) { + char *opstring; + if (node->isBinaryOperator()) + opstring = ((chillAST_BinaryOperator *) node)->op; // TODO enum + else + opstring = ((chillAST_UnaryOperator *) node)->op; // TODO enum + + if (!strcmp(opstring, "+")) return IR_OP_PLUS; + if (!strcmp(opstring, "-")) return IR_OP_MINUS; + if (!strcmp(opstring, "*")) return IR_OP_MULTIPLY; + if (!strcmp(opstring, "/")) return IR_OP_DIVIDE; + if (!strcmp(opstring, "=")) return IR_OP_ASSIGNMENT; + + CHILL_ERROR("UNHANDLED Binary(or Unary)Operator op type (%s)\n", opstring); + exit(-1); + } else if (node->isDeclRefExpr()) return IR_OP_VARIABLE; // ?? + //else if (node->is ) return something; + else { + CHILL_ERROR("IR_clangCode::QueryExpOperation() UNHANDLED NODE TYPE %s\n", node->getTypeString()); + exit(-1); + } + + /* CLANG + Expr *e = static_cast(repr)->GetExpression(); + if(isa(e) || isa(e)) return IR_OP_CONSTANT; + else if(isa(e)) return IR_OP_VARIABLE; + else if(BinaryOperator *bop = dyn_cast(e)) { + switch(bop->getOpcode()) { + case BO_Assign: return IR_OP_ASSIGNMENT; + case BO_Add: return IR_OP_PLUS; + case BO_Sub: return IR_OP_MINUS; + case BO_Mul: return IR_OP_MULTIPLY; + case BO_Div: return IR_OP_DIVIDE; + default: return IR_OP_UNKNOWN; + } + } else if(UnaryOperator *uop = dyn_cast(e)) { + switch(uop->getOpcode()) { + case UO_Minus: return IR_OP_NEGATIVE; + case UO_Plus: return IR_OP_POSITIVE; + default: return IR_OP_UNKNOWN; + } + } else if(ConditionalOperator *cop = dyn_cast(e)) { + BinaryOperator *bop; + if(bop = dyn_cast(cop->getCond())) { + if(bop->getOpcode() == BO_GT) return IR_OP_MAX; + else if(bop->getOpcode() == BO_LT) return IR_OP_MIN; + } else return IR_OP_UNKNOWN; + + } + + else if(e == NULL) return IR_OP_NULL; + else return IR_OP_UNKNOWN; + } + END CLANG */ +} + + +std::vector IR_clangCode::QueryExpOperand(const omega::CG_outputRepr *repr) const { + //fprintf(stderr, "IR_clangCode::QueryExpOperand()\n"); + std::vector v; + + CG_chillRepr *crepr = (CG_chillRepr *) repr; + //Expr *e = static_cast(repr)->GetExpression(); wrong.. CLANG + chillAST_Node *e = crepr->chillnodes[0]; // ?? + //e->print(); printf("\n"); fflush(stdout); + + // really need to be more rigorous than this hack // TODO + if (e->isImplicitCastExpr()) e = ((chillAST_ImplicitCastExpr *) e)->getSubExpr(); + if (e->isCStyleCastExpr()) e = ((chillAST_CStyleCastExpr *) e)->getSubExpr(); + if (e->isParenExpr()) e = ((chillAST_ParenExpr *) e)->getSubExpr(); + + + //if(isa(e) || isa(e) || isa(e)) { + if (e->isIntegerLiteral() || e->isFloatingLiteral() || e->isDeclRefExpr()) { + //fprintf(stderr, "it's a constant\n"); + omega::CG_chillRepr *repr = new omega::CG_chillRepr(e); + v.push_back(repr); + //} else if(BinaryOperator *bop = dyn_cast(e)) { + } else if (e->isBinaryOperator()) { + //fprintf(stderr, "ir_clang.cc BOP TODO\n"); exit(-1); // + chillAST_BinaryOperator *bop = (chillAST_BinaryOperator *) e; + char *op = bop->op; // TODO enum for operator types + if (!strcmp(op, "=")) { + v.push_back(new omega::CG_chillRepr(bop->getRHS())); // for assign, return RHS + } else if (!strcmp(op, "+") || !strcmp(op, "-") || !strcmp(op, "*") || !strcmp(op, "/")) { + v.push_back(new omega::CG_chillRepr(bop->getLHS())); // for +*-/ return both lhs and rhs + v.push_back(new omega::CG_chillRepr(bop->getRHS())); + } else { + CHILL_ERROR("Binary Operator UNHANDLED op (%s)\n", op); + exit(-1); + } + } // BinaryOperator + else if (e->isUnaryOperator()) { + omega::CG_chillRepr *repr; + chillAST_UnaryOperator *uop = (chillAST_UnaryOperator *) e; + char *op = uop->op; // TODO enum + if (!strcmp(op, "+") || !strcmp(op, "-")) { + v.push_back(new omega::CG_chillRepr(uop->getSubExpr())); + } else { + CHILL_ERROR("ir_clang.cc IR_clangCode::QueryExpOperand() Unary Operator UNHANDLED op (%s)\n", op); + exit(-1); + } + } // unaryoperator + else { + CHILL_ERROR("UNHANDLED node type %s\n", e->getTypeString()); + exit(-1); + } + + + /* +Expr *op1, *op2; + switch(bop->getOpcode()) { + case BO_Assign: + op2 = bop->getRHS(); + repr = new omega::CG_chillRepr(op2); + v.push_back(repr); + break; + case BO_Add: + case BO_Sub: + case BO_Mul: + case BO_Div: + op1 = bop->getLHS(); + repr = new omega::CG_chillRepr(op1); + v.push_back(repr); + op2 = bop->getRHS(); + repr = new omega::CG_chillRepr(op2); + v.push_back(repr); + break; + default: + throw chill::error::ir("operation not supported"); + } + */ + //} else if(UnaryOperator *uop = dyn_cast(e)) { + //} else if(e->isUnaryOperator()) { + /* + omega::CG_chillRepr *repr; + + switch(uop->getOpcode()) { + case UO_Minus: + case UO_Plus: + op1 = uop->getSubExpr(); + repr = new omega::CG_chillRepr(op1); + v.push_back(repr); + break; + default: + throw chill::error::ir("operation not supported"); + } + */ + //} else if(ConditionalOperator *cop = dyn_cast(e)) { + //omega::CG_chillRepr *repr; + + // TODO: Handle conditional operator here + //} else throw chill::error::ir("operand type UNsupported"); + + return v; +} + +IR_Ref *IR_clangCode::Repr2Ref(const omega::CG_outputRepr *repr) const { + CG_chillRepr *crepr = (CG_chillRepr *) repr; + chillAST_Node *node = crepr->chillnodes[0]; + + if (node->isIntegerLiteral()) { + // FIXME: Not sure if it'll work in all cases (long?) + int val = ((chillAST_IntegerLiteral *) node)->value; + return new IR_chillConstantRef(this, static_cast(val)); + } else if (node->isFloatingLiteral()) { + float val = ((chillAST_FloatingLiteral *) node)->value; + return new IR_chillConstantRef(this, val); + } else if (node->isDeclRefExpr()) { + return new IR_chillScalarRef(this, (chillAST_DeclRefExpr *) node); // uses DRE + } else { + CHILL_ERROR("ir_clang.cc IR_clangCode::Repr2Ref() UNHANDLED node type %s\n", node->getTypeString()); + exit(-1); + } +} + + + +omega::CG_outputRepr *IR_chillIf::condition() const { + assert( code->isIfStmt() && "If statement's code is not if statement"); + return new omega::CG_chillRepr(((chillAST_IfStmt*)code) -> getCond()); +} + +IR_Block *IR_chillIf::then_body() const { + assert( code->isIfStmt() && "If statement's code is not if statement"); + chillAST_Node* thenPart = ((chillAST_IfStmt*)code) -> getThen(); + if (thenPart) return new IR_chillBlock(ir_,thenPart); + return NULL; +} + +IR_Block *IR_chillIf::else_body() const { + assert( code->isIfStmt() && "If statement's code is not if statement"); + chillAST_Node* elsePart = ((chillAST_IfStmt*)code) -> getElse(); + if (elsePart) return new IR_chillBlock(ir_,elsePart); + return NULL; +} + +IR_Block *IR_chillIf::convert() { + const IR_Code *ir = ir_; + chillAST_Node *code = this->code; + delete this; + return new IR_chillBlock(ir,code); +} + +IR_Control *IR_chillIf::clone() const { + return new IR_chillIf(ir_,code); +} diff --git a/src/ir_clang.cc b/src/ir_clang.cc deleted file mode 100755 index f31a0ac..0000000 --- a/src/ir_clang.cc +++ /dev/null @@ -1,2350 +0,0 @@ -/***************************************************************************** - Copyright (C) 2009-2010 University of Utah - All Rights Reserved. - -Purpose: -CHiLL's CLANG interface. -convert from CLANG AST to chill AST - -Notes: -Array supports mixed pointer and array type in a single declaration. - -History: -12/10/2010 LLVM/CLANG Interface created by Saurav Muralidharan. - *****************************************************************************/ - -#include -#include -#include "ir_clang.hh" -#include "loop.hh" -#include "chill_error.hh" - -#include "clang/Frontend/FrontendActions.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "code_gen/CG_chillRepr.h" -#include "code_gen/CG_chillBuilder.h" -#include -#include - -#include "chillAST.h" - -#define NL_RET(x) {chillAST_NodeList *ret = new chillAST_NodeList(); \ - ret->push_back(x); \ - return ret;} - -// TODO move to ir_clang.hh - -chillAST_NodeList* ConvertTypeDefDecl(clang::TypedefDecl *TDD); - -chillAST_NodeList* ConvertRecordDecl(clang::RecordDecl *D); - -chillAST_NodeList* ConvertDeclStmt(clang::DeclStmt *clangDS); - -chillAST_NodeList* ConvertCompoundStmt(clang::CompoundStmt *clangCS); - -chillAST_NodeList* ConvertFunctionDecl(clang::FunctionDecl *D); - -chillAST_NodeList* ConvertForStmt(clang::ForStmt *clangFS); - -chillAST_NodeList* ConvertUnaryOperator(clang::UnaryOperator *clangU); - -chillAST_NodeList* ConvertBinaryOperator(clang::BinaryOperator *clangBO); - -chillAST_NodeList* ConvertArraySubscriptExpr(clang::ArraySubscriptExpr *clangASE); - -chillAST_NodeList* ConvertDeclRefExpr(clang::DeclRefExpr *clangDRE); - -chillAST_NodeList* ConvertIntegerLiteral(clang::IntegerLiteral *clangIL); - -chillAST_NodeList* ConvertFloatingLiteral(clang::FloatingLiteral *clangFL); - -chillAST_NodeList* ConvertImplicitCastExpr(clang::ImplicitCastExpr *clangICE); - -chillAST_NodeList* ConvertCStyleCastExpr(clang::CStyleCastExpr *clangICE); - -chillAST_NodeList* ConvertReturnStmt(clang::ReturnStmt *clangRS); - -chillAST_NodeList* ConvertCallExpr(clang::CallExpr *clangCE); - -chillAST_NodeList* ConvertIfStmt(clang::IfStmt *clangIS); - -chillAST_NodeList* ConvertMemberExpr(clang::MemberExpr *clangME); - - -chillAST_NodeList* ConvertTranslationUnit(clang::TranslationUnitDecl *TUD, char *filename); - -/*! - * \brief Convert fon Clang AST to CHiLL AST also append to parent node p if necessary - * - * @param s Clang statement - * @return A set of new statements - */ -chillAST_NodeList* ConvertGenericClangAST(clang::Stmt *s); - - -std::vector VariableDeclarations; -std::vector FunctionDeclarations; - -using namespace clang; -using namespace clang::driver; -using namespace omega; -using namespace std; - - -static string binops[] = { - " ", " ", // BO_PtrMemD, BO_PtrMemI, // [C++ 5.5] Pointer-to-member operators. - "*", "/", "%", // BO_Mul, BO_Div, BO_Rem, // [C99 6.5.5] Multiplicative operators. - "+", "-", // BO_Add, BO_Sub, // [C99 6.5.6] Additive operators. - "<<", ">>", // BO_Shl, BO_Shr, // [C99 6.5.7] Bitwise shift operators. - "<", ">", "<=", ">=", // BO_LT, BO_GT, BO_LE, BO_GE, // [C99 6.5.8] Relational operators. - "==", "!=", // BO_EQ, BO_NE, // [C99 6.5.9] Equality operators. - "&", // BO_And, // [C99 6.5.10] Bitwise AND operator. - "??", // BO_Xor, // [C99 6.5.11] Bitwise XOR operator. - "|", // BO_Or, // [C99 6.5.12] Bitwise OR operator. - "&&", // BO_LAnd, // [C99 6.5.13] Logical AND operator. - "||", // BO_LOr, // [C99 6.5.14] Logical OR operator. - "=", "*=", // BO_Assign, BO_MulAssign, // [C99 6.5.16] Assignment operators. - "/=", "%=", // BO_DivAssign, BO_RemAssign, - "+=", "-=", // BO_AddAssign, BO_SubAssign, - "???", "???", // BO_ShlAssign, BO_ShrAssign, - "&&=", "???", // BO_AndAssign, BO_XorAssign, - "||=", // BO_OrAssign, - ","}; // BO_Comma // [C99 6.5.17] Comma operator. - - -static string unops[] = { - "++", "--", // [C99 6.5.2.4] Postfix increment and decrement - "++", "--", // [C99 6.5.3.1] Prefix increment and decrement - "@", "*", // [C99 6.5.3.2] Address and indirection - "+", "-", // [C99 6.5.3.3] Unary arithmetic - "~", "!", // [C99 6.5.3.3] Unary arithmetic - "__real", "__imag", // "__real expr"/"__imag expr" Extension. - "__extension" // __extension__ marker. -}; - -// forward defs -SourceManager *globalSRCMAN; // ugly. shame. - -char *splitTypeInfo(char *underlyingtype); - -chillAST_Node* unwrap(chillAST_NodeList* nl){ - chillAST_Node* n; - if (!nl || !nl->size()) n = NULL; - else n = (*nl)[0]; - delete nl; - return n; -} - -chillAST_NodeList* ConvertVarDecl(VarDecl *D) { - bool isParm = false; - - QualType T0 = D->getType(); - QualType T = T0; - if (ParmVarDecl *Parm = dyn_cast(D)) { // My GOD clang stinks - T = Parm->getOriginalType(); - isParm = true; - } - - char *vartype = strdup(T.getAsString().c_str()); - char *arraypart = splitTypeInfo(vartype); - - char *varname = strdup(D->getName().str().c_str()); - - chillAST_VarDecl *chillVD = new chillAST_VarDecl(vartype, varname, arraypart, (void *) D); - - chillVD->isAParameter = isParm; - - int numdim = 0; - chillVD->knownArraySizes = true; - if (index(vartype, '*')) chillVD->knownArraySizes = false; // float *a; for example - if (index(arraypart, '*')) chillVD->knownArraySizes = false; - - // note: vartype here, arraypart in next code.. is that right? - if (index(vartype, '*')) { - for (int i = 0; i < strlen(vartype); i++) if (vartype[i] == '*') numdim++; - chillVD->numdimensions = numdim; - } - - if (index(arraypart, '[')) { // JUST [12][34][56] no asterisks - char *dupe = strdup(arraypart); - - int len = strlen(arraypart); - for (int i = 0; i < len; i++) if (dupe[i] == '[') numdim++; - - chillVD->numdimensions = numdim; - int *as = (int *) malloc(sizeof(int *) * numdim); - if (!as) { - fprintf(stderr, "can't malloc array sizes in ConvertVarDecl()\n"); - exit(-1); - } - chillVD->arraysizes = as; // 'as' changed later! - - - char *ptr = dupe; - while (ptr = index(ptr, '[')) { - ptr++; - int dim; - sscanf(ptr, "%d", &dim); - *as++ = dim; - - ptr = index(ptr, ']'); - } - free(dupe); - } - - Expr *Init = D->getInit(); - if (Init) { - fprintf(stderr, " = VARDECL HAS INIT. (TODO) (RIGHT NOW)"); - exit(-1); - } - - free(vartype); - free(varname); - - VariableDeclarations.push_back(chillVD); - - NL_RET(chillVD); -} - - -chillAST_NodeList* ConvertRecordDecl(clang::RecordDecl *RD) { // for structs and unions - - //fprintf(stderr, "ConvertRecordDecl( )\n\nclang sees\n"); - //RD->dump(); - //fflush(stdout); - //fprintf(stderr, "\n"); - - //fprintf(stderr, "%s with name %s\n", ((clang::Decl *)RD)->getDeclKindName(), RD->getNameAsString().c_str()); - //const clang::ASTRecordLayout RL = RD->getASTContext().getASTRecordLayout( RD ); - //RD->getASTContext().DumpRecordLayout( RD , cout ); - - int count = 0; - for (clang::RecordDecl::field_iterator fi = RD->field_begin(); fi != RD->field_end(); fi++) count++; - //fprintf(stderr, "%d fields in this struct/union\n", count); - - char blurb[128]; - sprintf(blurb, "struct %s", RD->getNameAsString().c_str()); - fprintf(stderr, "blurb is '%s'\n", blurb); - - chillAST_TypedefDecl *astruct = new chillAST_TypedefDecl(blurb, "", NULL); - astruct->setStruct(true); - astruct->setStructName(RD->getNameAsString().c_str()); - - for (clang::RecordDecl::field_iterator fi = RD->field_begin(); fi != RD->field_end(); fi++) { - clang::FieldDecl *FD = (*fi); - FD->dump(); - printf(";\n"); - fflush(stdout); - string TypeStr = FD->getType().getAsString(); - - const char *typ = TypeStr.c_str(); - const char *name = FD->getNameAsString().c_str(); - fprintf(stderr, "(typ) %s (name) %s\n", typ, name); - - chillAST_VarDecl *VD = NULL; - // very clunky and incomplete - VD = new chillAST_VarDecl(typ, name, "", astruct); // can't handle arrays yet - - astruct->subparts.push_back(VD); - } - - - fprintf(stderr, "I just defined a struct\n"); - astruct->print(0, stderr); - - NL_RET(astruct); -} - - -chillAST_NodeList* ConvertTypeDefDecl(TypedefDecl *TDD) { - //fprintf(stderr, "ConvertTypedefDecl( ) \n"); - //fprintf(stderr, "TDD has type %s\n", TDD->getDeclKindName()); - //TDD->dump(); fprintf(stderr, "\n"); - - char *under = strdup(TDD->getUnderlyingType().getAsString().c_str()); - //fprintf(stderr, "under = '%s'\n", under); - char *arraypart = splitTypeInfo(under); - //fprintf(stderr, "typedef %s %s%s;\n", under, TDD->getName().str().c_str(), arraypart); - // fprintf(stderr, "len arraypart = %d\n", strlen(arraypart)); - char *alias = strdup(TDD->getName().str().c_str()); - - //fprintf(stderr, "underlying type %s arraypart '%s' name %s\n", under, arraypart, TDD->getName().str().c_str() ); - chillAST_TypedefDecl *CTDD = new chillAST_TypedefDecl(under, alias, arraypart); - - free(under); - free(arraypart); - - NL_RET(CTDD); -} - - -chillAST_NodeList* ConvertDeclStmt(DeclStmt *clangDS) { - //fprintf(stderr, "ConvertDeclStmt()\n"); - - chillAST_VarDecl *chillvardecl; // the thing we'll return if this is a single declaration - - bool multiples = !clangDS->isSingleDecl(); - - DeclGroupRef dgr = clangDS->getDeclGroup(); - clang::DeclGroupRef::iterator DI = dgr.begin(); - clang::DeclGroupRef::iterator DE = dgr.end(); - chillAST_NodeList* decls = new chillAST_NodeList(); - - for (; DI != DE; ++DI) { - Decl *D = *DI; - const char *declty = D->getDeclKindName(); - //fprintf(stderr, "a decl of type %s\n", D->getDeclKindName()); - - if (!strcmp("Var", declty)) { - VarDecl *V = dyn_cast(D); - // ValueDecl *VD = dyn_cast(D); // not needed? - std::string Name = V->getNameAsString(); - char *varname = strdup(Name.c_str()); - - //fprintf(stderr, "variable named %s\n", Name.c_str()); - QualType T = V->getType(); - string TypeStr = T.getAsString(); - char *vartype = strdup(TypeStr.c_str()); - - CHILL_DEBUG_PRINT("DeclStmt (clang 0x%x) for %s %s\n", D, vartype, varname); - //fprintf(stderr, "%s %s\n", td, varname); - char *arraypart = splitTypeInfo(vartype); - - chillvardecl = new chillAST_VarDecl(vartype, varname, arraypart, (void *) D); - - // store this away for declrefexpr that references it! - VariableDeclarations.push_back(chillvardecl); - decls->push_back(chillvardecl); - - // TODO - if (V->hasInit()) { - CHILL_ERROR(" ConvertDeclStmt() UNHANDLED initialization\n"); - exit(-1); - } - } - } // for each of possibly multiple decls - - return decls; -} - - -chillAST_NodeList* ConvertCompoundStmt(CompoundStmt *clangCS) { - int numchildren = clangCS->size(); - - // make an empty CHILL compound statement - chillAST_CompoundStmt *chillCS = new chillAST_CompoundStmt; - - // for each clang child - for (auto I = clangCS->child_begin(); I != clangCS->child_end(); ++I) { // ?? loop looks WRONG - // create the chill ast for each child - Stmt *child = *I; - chillAST_NodeList* nl = ConvertGenericClangAST(child); - // usually n will be a statement. We just add it as a child. - // SOME DeclStmts have multiple declarations. They will add themselves and return NULL - chillCS->addChildren(*nl); - delete nl; - } - - NL_RET(chillCS); -} - - -chillAST_NodeList* ConvertFunctionDecl(FunctionDecl *D) { - QualType QT = D->getReturnType(); - string ReturnTypeStr = QT.getAsString(); - - // Function name - DeclarationName DeclName = D->getNameInfo().getName(); - string FuncName = DeclName.getAsString(); - - chillAST_FunctionDecl *chillFD = new chillAST_FunctionDecl(ReturnTypeStr.c_str(), FuncName.c_str(), D); - - - int numparams = D->getNumParams(); - - CHILL_DEBUG_PRINT(" %d parameters\n", numparams); - for (int i = 0; i < numparams; i++) { - VarDecl *clangvardecl = D->getParamDecl(i); // the ith parameter (CLANG) - ParmVarDecl *pvd = D->getParamDecl(i); - QualType T = pvd->getOriginalType(); - CHILL_DEBUG_PRINT("OTYPE %s\n", T.getAsString().c_str()); - - chillAST_NodeList* nl = ConvertVarDecl(clangvardecl); - chillAST_VarDecl* decl = (chillAST_VarDecl*)unwrap(nl); - //chillPVD->print(); fflush(stdout); - - //chillPVD->isAParameter = 1; - VariableDeclarations.push_back(decl); - - chillFD->addParameter(decl); - CHILL_DEBUG_PRINT("chillAST ParmVarDecl for %s from chill location 0x%x\n", decl->varname, clangvardecl); - } // for each parameter - - - - //fprintf(stderr, ")\n{\n"); // beginning of function body - //if (D->isExternC()) { chillFD->setExtern(); fprintf(stderr, "%s is extern\n", FuncName.c_str()); }; - if (D->getBuiltinID()) { - chillFD->setExtern(); - CHILL_DEBUG_PRINT("%s is builtin (extern)\n", FuncName.c_str()); - }; - - Stmt *clangbody = D->getBody(); - if (clangbody) { // may just be fwd decl or external, without an actual body - //fprintf(stderr, "body of type %s\n", clangbody->getStmtClassName()); - //chillAST_Node *CB = ConvertCompoundStmt( dyn_cast(clangbody) ); // always a compound statement? - chillAST_NodeList* nl = ConvertGenericClangAST(clangbody); - //fprintf(stderr, "FunctionDecl body = 0x%x of type %s\n", CB, CB->getTypeString()); - chillFD->setBody(unwrap(nl)); - } - - //fprintf(stderr, "adding function %s 0x%x to FunctionDeclarations\n", chillFD->functionName, chillFD); - FunctionDeclarations.push_back(chillFD); - NL_RET(chillFD); -} - - -chillAST_NodeList* ConvertForStmt(ForStmt *clangFS) { - - chillAST_Node *init = unwrap(ConvertGenericClangAST(clangFS->getInit())); - chillAST_Node *cond = unwrap(ConvertGenericClangAST(clangFS->getCond())); - chillAST_Node *incr = unwrap(ConvertGenericClangAST(clangFS->getInc())); - chillAST_Node *body = unwrap(ConvertGenericClangAST(clangFS->getBody())); - if (body->getType() != CHILLAST_NODE_COMPOUNDSTMT) { - // make single statement loop bodies loop like other loops - CHILL_DEBUG_PRINT("ForStmt body of type %s\n", body->getTypeString()); - chillAST_CompoundStmt *cs = new chillAST_CompoundStmt(); - cs->addChild(body); - body = cs; - } - chillAST_ForStmt *chill_loop = new chillAST_ForStmt(init, cond, incr, body); - NL_RET(chill_loop); -} - - -chillAST_NodeList* ConvertIfStmt(IfStmt *clangIS) { - Expr *cond = clangIS->getCond(); - Stmt *thenpart = clangIS->getThen(); - Stmt *elsepart = clangIS->getElse(); - - chillAST_Node *con = unwrap(ConvertGenericClangAST(cond)); - chillAST_Node *thn = NULL; - if (thenpart) { - thn = unwrap(ConvertGenericClangAST(thenpart)); - if (!thn->isCompoundStmt()) { - chillAST_Node* tmp=new chillAST_CompoundStmt(); - tmp->addChild(thn); - thn = tmp; - } - } - chillAST_Node *els = NULL; - if (elsepart) { - els = unwrap(ConvertGenericClangAST(elsepart)); - if (!els->isCompoundStmt()) { - chillAST_Node* tmp=new chillAST_CompoundStmt(); - tmp->addChild(els); - els = tmp; - } - } - - chillAST_IfStmt *ifstmt = new chillAST_IfStmt(con, thn, els); - NL_RET(ifstmt); -} - - -chillAST_NodeList* ConvertUnaryOperator(UnaryOperator *clangUO) { - const char *op = unops[clangUO->getOpcode()].c_str(); - bool pre = clangUO->isPrefix(); - chillAST_Node *sub = unwrap(ConvertGenericClangAST(clangUO->getSubExpr())); - - chillAST_UnaryOperator *chillUO = new chillAST_UnaryOperator(op, pre, sub); - NL_RET(chillUO); -} - - -chillAST_NodeList* ConvertBinaryOperator(BinaryOperator *clangBO) { - - // get the clang parts - Expr *lhs = clangBO->getLHS(); - Expr *rhs = clangBO->getRHS(); - BinaryOperator::Opcode op = clangBO->getOpcode(); // this is CLANG op, not CHILL op - - - // convert to chill equivalents - chillAST_Node *l = unwrap(ConvertGenericClangAST(lhs)); - const char *opstring = binops[op].c_str(); - chillAST_Node *r = unwrap(ConvertGenericClangAST(rhs)); - // TODO chill equivalent for numeric op. - - // build up the chill Binary Op AST node - chillAST_BinaryOperator *binop = new chillAST_BinaryOperator(l, opstring, r); - - NL_RET(binop); -} - - -chillAST_NodeList* ConvertArraySubscriptExpr(ArraySubscriptExpr *clangASE) { - - Expr *clangbase = clangASE->getBase(); - Expr *clangindex = clangASE->getIdx(); - //fprintf(stderr, "clang base: "); clangbase->dump(); fprintf(stderr, "\n"); - - chillAST_Node *bas = unwrap(ConvertGenericClangAST(clangbase)); - chillAST_Node *indx = unwrap(ConvertGenericClangAST(clangindex)); - - // TODO clangAST contamination - chillAST_ArraySubscriptExpr *chillASE = new chillAST_ArraySubscriptExpr(bas, indx, NULL, clangASE); - NL_RET(chillASE); -} - - -chillAST_NodeList* ConvertDeclRefExpr(DeclRefExpr *clangDRE) { - DeclarationNameInfo DNI = clangDRE->getNameInfo(); - - ValueDecl *vd = static_cast(clangDRE->getDecl()); // ValueDecl ?? VarDecl ?? - - QualType QT = vd->getType(); - string TypeStr = QT.getAsString(); - //fprintf(stderr, "\n\n*** type %s ***\n\n", TypeStr.c_str()); - //fprintf(stderr, "kind %s\n", vd->getDeclKindName()); - - DeclarationName DN = DNI.getName(); - const char *varname = DN.getAsString().c_str(); - chillAST_DeclRefExpr *chillDRE = new chillAST_DeclRefExpr(TypeStr.c_str(), varname, NULL); - - //fprintf(stderr, "clang DeclRefExpr refers to declaration of %s @ 0x%x\n", varname, vd); - //fprintf(stderr, "clang DeclRefExpr refers to declaration of %s of kind %s\n", varname, vd->getDeclKindName()); - - // find the definition (we hope) - if ((!strcmp("Var", vd->getDeclKindName())) || (!strcmp("ParmVar", vd->getDeclKindName()))) { - // it's a variable reference - int numvars = VariableDeclarations.size(); - chillAST_VarDecl *chillvd = NULL; - for (int i = 0; i < numvars; i++) { - if (VariableDeclarations[i]->uniquePtr == vd) { - chillvd = VariableDeclarations[i]; - //fprintf(stderr, "found it at variabledeclaration %d of %d\n", i, numvars); - } - } - if (!chillvd) { - fprintf(stderr, "\nWARNING, ir_clang.cc clang DeclRefExpr %s refers to a declaration I can't find! at ox%x\n", - varname, vd); - fprintf(stderr, "variables I know of are:\n"); - for (int i = 0; i < numvars; i++) { - chillAST_VarDecl *adecl = VariableDeclarations[i]; - if (adecl->isParmVarDecl()) fprintf(stderr, "(parameter) "); - fprintf(stderr, "%s %s at location 0x%x\n", adecl->vartype, adecl->varname, adecl->uniquePtr); - } - fprintf(stderr, "\n"); - } - - if (chillvd == NULL) { - fprintf(stderr, "chillDRE->decl = 0x%x\n", chillvd); - exit(-1); - } - - chillDRE->decl = (chillAST_Node *) chillvd; // start of spaghetti pointers ... - } else if (!strcmp("Function", vd->getDeclKindName())) { - //fprintf(stderr, "declrefexpr of type Function\n"); - int numfuncs = FunctionDeclarations.size(); - chillAST_FunctionDecl *chillfd = NULL; - for (int i = 0; i < numfuncs; i++) { - if (FunctionDeclarations[i]->uniquePtr == vd) { - chillfd = FunctionDeclarations[i]; - //fprintf(stderr, "found it at functiondeclaration %d of %d\n", i, numfuncs); - } - } - if (chillfd == NULL) { - fprintf(stderr, "chillDRE->decl = 0x%x\n", chillfd); - exit(-1); - } - - chillDRE->decl = (chillAST_Node *) chillfd; // start of spaghetti pointers ... - - } else { - fprintf(stderr, "clang DeclRefExpr refers to declaration of %s of kind %s\n", varname, vd->getDeclKindName()); - fprintf(stderr, "chillDRE->decl = UNDEFINED\n"); - exit(-1); - } - - //fprintf(stderr, "%s\n", DN.getAsString().c_str()); - NL_RET(chillDRE); -} - - -chillAST_NodeList* ConvertIntegerLiteral(IntegerLiteral *clangIL) { - bool isSigned = clangIL->getType()->isSignedIntegerType(); - //int val = clangIL->getIntValue(); - const char *printable = clangIL->getValue().toString(10, isSigned).c_str(); - int val = atoi(printable); - //fprintf(stderr, "int value %s (%d)\n", printable, val); - chillAST_IntegerLiteral *chillIL = new chillAST_IntegerLiteral(val); - NL_RET(chillIL); -} - - -chillAST_NodeList* ConvertFloatingLiteral(FloatingLiteral *clangFL) { - //fprintf(stderr, "\nConvertFloatingLiteral()\n"); - float val = clangFL->getValueAsApproximateDouble(); // TODO approx is a bad idea! - string WHAT; - SmallString<16> Str; - clangFL->getValue().toString(Str); - const char *printable = Str.c_str(); - //fprintf(stderr, "literal %s\n", printable); - - SourceLocation sloc = clangFL->getLocStart(); - SourceLocation eloc = clangFL->getLocEnd(); - - std::string start = sloc.printToString(*globalSRCMAN); - std::string end = eloc.printToString(*globalSRCMAN); - //fprintf(stderr, "literal try2 start %s end %s\n", start.c_str(), end.c_str()); - //printlines( sloc, eloc, globalSRCMAN ); - unsigned int startlineno = globalSRCMAN->getPresumedLineNumber(sloc); - unsigned int endlineno = globalSRCMAN->getPresumedLineNumber(eloc);; - const char *filename = globalSRCMAN->getBufferName(sloc); - - std::string fname = globalSRCMAN->getFilename(sloc); - //fprintf(stderr, "fname %s\n", fname.c_str()); - - if (filename && strlen(filename) > 0) {} // fprintf(stderr, "literal file '%s'\n", filename); - else { - fprintf(stderr, "\nConvertFloatingLiteral() filename is NULL?\n"); - - //sloc = globalSRCMAN->getFileLoc( sloc ); // should get spelling loc? - sloc = globalSRCMAN->getSpellingLoc(sloc); // should get spelling loc? - //eloc = globalSRCMAN->getFileLoc( eloc ); - - start = sloc.printToString(*globalSRCMAN); - //end = eloc.printToString( *globalSRCMAN ); - //fprintf(stderr, "literal try3 start %s end %s\n", start.c_str(), end.c_str()); - - startlineno = globalSRCMAN->getPresumedLineNumber(sloc); - //endlineno = globalSRCMAN->getPresumedLineNumber( eloc ); ; - //fprintf(stderr, "start, end line numbers %d %d\n", startlineno, endlineno); - - filename = globalSRCMAN->getBufferName(sloc); - - //if (globalSRCMAN->isMacroBodyExpansion( sloc )) { - // fprintf(stderr, "IS MACRO\n"); - //} - } - - unsigned int offset = globalSRCMAN->getFileOffset(sloc); - //fprintf(stderr, "literal file offset %d\n", offset); - - FILE *fp = fopen(filename, "r"); - fseek(fp, offset, SEEK_SET); // go to the part of the file where the float is defined - - char buf[10240]; - fgets(buf, sizeof(buf), fp); // read a line starting where the float starts - fclose(fp); - - // buf has the line we want grab the float constant out of it - //fprintf(stderr, "\nbuf '%s'\n", buf); - char *ptr = buf; - if (*ptr == '-') ptr++; // ignore possible minus sign - int len = strspn(ptr, ".-0123456789f"); - buf[len] = '\0'; - //fprintf(stderr, "'%s'\n", buf); - - chillAST_FloatingLiteral *chillFL = new chillAST_FloatingLiteral(val,1, buf); - - //chillFL->print(); printf("\n"); fflush(stdout); - NL_RET(chillFL); -} - - -chillAST_NodeList* ConvertImplicitCastExpr(ImplicitCastExpr *clangICE) { - //fprintf(stderr, "ConvertImplicitCastExpr()\n"); - CastExpr *CE = dyn_cast(clangICE); - //fprintf(stderr, "implicit cast of type %s\n", CE->getCastKindName()); - chillAST_Node *sub = unwrap(ConvertGenericClangAST(clangICE->getSubExpr())); - chillAST_ImplicitCastExpr *chillICE = new chillAST_ImplicitCastExpr(sub); - - //sub->setParent( chillICE ); // these 2 lines work - //return chillICE; - - //sub->setParent(p); // ignore the ImplicitCastExpr !! TODO (probably a bad idea) - NL_RET(chillICE); -} - - -chillAST_NodeList* ConvertCStyleCastExpr(CStyleCastExpr *clangCSCE) { - CastExpr *CE = dyn_cast(clangCSCE); - - const char *towhat = strdup(clangCSCE->getTypeAsWritten().getAsString().c_str()); - - chillAST_Node *sub = unwrap(ConvertGenericClangAST(clangCSCE->getSubExprAsWritten())); - chillAST_CStyleCastExpr *chillCSCE = new chillAST_CStyleCastExpr(towhat, sub); - NL_RET(chillCSCE); -} - - -chillAST_NodeList* ConvertReturnStmt(ReturnStmt *clangRS) { - chillAST_Node *retval = unwrap(ConvertGenericClangAST(clangRS->getRetValue())); // NULL is handled - //if (retval == NULL) fprintf(stderr, "return stmt returns nothing\n"); - - chillAST_ReturnStmt *chillRS = new chillAST_ReturnStmt(retval); - NL_RET(chillRS); -} - - -chillAST_NodeList* ConvertCallExpr(CallExpr *clangCE) { - //fprintf(stderr, "ConvertCallExpr()\n"); - - chillAST_Node *callee = unwrap(ConvertGenericClangAST(clangCE->getCallee())); - //fprintf(stderr, "callee is of type %s\n", callee->getTypeString()); - - //chillAST_Node *next = ((chillAST_ImplicitCastExpr *)callee)->subexpr; - //fprintf(stderr, "callee is of type %s\n", next->getTypeString()); - - chillAST_CallExpr *chillCE = new chillAST_CallExpr(callee); - - int numargs = clangCE->getNumArgs(); - //fprintf(stderr, "CallExpr has %d args\n", numargs); - Expr **clangargs = clangCE->getArgs(); - for (int i = 0; i < numargs; i++) { - chillCE->addArg(unwrap(ConvertGenericClangAST(clangargs[i]))); - } - - NL_RET(chillCE); -} - - -chillAST_NodeList* ConvertParenExpr(ParenExpr *clangPE) { - chillAST_Node *sub = unwrap(ConvertGenericClangAST(clangPE->getSubExpr())); - chillAST_ParenExpr *chillPE = new chillAST_ParenExpr(sub); - - NL_RET(chillPE); -} - - -chillAST_NodeList* ConvertTranslationUnit(TranslationUnitDecl *TUD, char *filename) { - static DeclContext *DC = TUD->castToDeclContext(TUD); - - chillAST_SourceFile *topnode = new chillAST_SourceFile(filename); - topnode->setFrontend("clang"); - topnode->chill_array_counter = 1; - topnode->chill_scalar_counter = 0; - - // now recursively build clang AST from the children of TUD - DeclContext::decl_iterator start = DC->decls_begin(); - DeclContext::decl_iterator end = DC->decls_end(); - for (DeclContext::decl_iterator DI = start; DI != end; ++DI) { - Decl *D = *DI; - chillAST_Node *child; - // Skip internal declarations of clang - - if (isa(D)) { - child = unwrap(ConvertFunctionDecl(dyn_cast(D))); - } else if (isa(D)) { - child = unwrap(ConvertVarDecl(dyn_cast(D))); - } else if (isa(D)) { - child = unwrap(ConvertTypeDefDecl(dyn_cast(D))); - } else if (isa(D)) { - CHILL_DEBUG_PRINT("\nTUD RecordDecl\n"); - child = unwrap(ConvertRecordDecl(dyn_cast(D))); - } else if (isa(D)) { - CHILL_ERROR("TUD TypeAliasDecl TODO \n"); - exit(-1); - } else { - CHILL_ERROR("\nTUD a declaration of type %s (%d) which I can't handle\n", D->getDeclKindName(), D->getKind()); - exit(-1); - } - topnode -> addChild(child); - - if (D->isImplicit() || !globalSRCMAN->getFilename(D->getLocation()).equals(filename)) child->isFromSourceFile = false; - } - - NL_RET(topnode); -} - - -chillAST_NodeList* ConvertGenericClangAST(Stmt *s) { - - if (s == NULL) return NULL; - Decl *D = (Decl *) s; - - chillAST_NodeList *ret = NULL; // find the SINGLE constant or data reference at this node or below - - if (isa(s)) { - ret = ConvertCompoundStmt(dyn_cast(s)); - } else if (isa(s)) { - ret = ConvertDeclStmt(dyn_cast(s)); - } else if (isa(s)) { - ret = ConvertForStmt(dyn_cast(s)); - } else if (isa(s)) { - ret = ConvertBinaryOperator(dyn_cast(s)); - } else if (isa(s)) { - ret = ConvertArraySubscriptExpr(dyn_cast(s)); - } else if (isa(s)) { - ret = ConvertDeclRefExpr(dyn_cast(s)); - } else if (isa(s)) { - ret = ConvertFloatingLiteral(dyn_cast(s)); - } else if (isa(s)) { - ret = ConvertIntegerLiteral(dyn_cast(s)); - } else if (isa(s)) { - ret = ConvertUnaryOperator(dyn_cast(s)); - } else if (isa(s)) { - ret = ConvertImplicitCastExpr(dyn_cast(s)); - } else if (isa(s)) { - ret = ConvertCStyleCastExpr(dyn_cast(s)); - } else if (isa(s)) { - ret = ConvertReturnStmt(dyn_cast(s)); - } else if (isa(s)) { - ret = ConvertCallExpr(dyn_cast(s)); - } else if (isa(s)) { - ret = ConvertParenExpr(dyn_cast(s)); - } else if (isa(s)) { - ret = ConvertIfStmt(dyn_cast(s)); - } else if (isa(s)) { - ret = ConvertMemberExpr(dyn_cast(s)); - - - // these can only happen at the top level? - // } else if (isa(D)) { ret = ConvertFunctionDecl( dyn_cast(D)); - //} else if (isa(D)) { ret = ConvertVarDecl( dyn_cast(D) ); - //} else if (isa(D)) { ret = ConvertTypeDefDecl( dyn_cast(D)); - // else if (isa(s)) // need filename - - - - - // } else if (isa<>(s)) { Convert ( dyn_cast<>(s)); - - /* - */ - - } else { - // more work to do - if (isa(D)) CHILL_ERROR("Decl of kind %s unhandled\n", D->getDeclKindName() ); - if (isa(s)) CHILL_ERROR("Stmt of type %s unhandled\n", s->getStmtClassName()); - exit(-1); - } - - return ret; -} - -// ---------------------------------------------------------------------------- -// Class: IR_chillScalarSymbol -// ---------------------------------------------------------------------------- - -std::string IR_chillScalarSymbol::name() const { - return std::string(chillvd->varname); // CHILL -} - - -// Return size in bytes -int IR_chillScalarSymbol::size() const { - CHILL_DEBUG_PRINT("IR_chillScalarSymbol::size() probably WRONG\n"); - return (8); // bytes?? -} - - -bool IR_chillScalarSymbol::operator==(const IR_Symbol &that) const { - //fprintf(stderr, "IR_xxxxScalarSymbol::operator== probably WRONG\n"); - if (typeid(*this) != typeid(that)) - return false; - - const IR_chillScalarSymbol *l_that = static_cast(&that); - return this->chillvd == l_that->chillvd; -} - -IR_Symbol *IR_chillScalarSymbol::clone() const { - return new IR_chillScalarSymbol(ir_, chillvd); // clone -} - -// ---------------------------------------------------------------------------- -// Class: IR_chillArraySymbol -// ---------------------------------------------------------------------------- - -std::string IR_chillArraySymbol::name() const { - return std::string(strdup(chillvd->varname)); -} - - -int IR_chillArraySymbol::elem_size() const { - fprintf(stderr, "IR_chillArraySymbol::elem_size() TODO\n"); - exit(-1); - return 8; // TODO - //const ArrayType *at = dyn_cast(vd_->getType()); - //if(at) { - // return (vd_->getASTContext().getTypeSize(at->getElementType())) / 8; - //} else - // throw chill::error::ir("Symbol is not an array!"); - //return 0; -} - - -int IR_chillArraySymbol::n_dim() const { - return chillvd->numdimensions; -} - - -// TODO -omega::CG_outputRepr *IR_chillArraySymbol::size(int dim) const { - CHILL_ERROR("IR_chillArraySymbol::n_size() TODO \n"); - exit(-1); - return NULL; -} - - -bool IR_chillArraySymbol::operator!=(const IR_Symbol &that) const { - return chillvd != ((IR_chillArraySymbol *) &that)->chillvd; -} - -bool IR_chillArraySymbol::operator==(const IR_Symbol &that) const { - return chillvd == ((IR_chillArraySymbol *) &that)->chillvd; -} - - -IR_Symbol *IR_chillArraySymbol::clone() const { - return new IR_chillArraySymbol(ir_, chillvd, offset_); -} - -// ---------------------------------------------------------------------------- -// Class: IR_chillConstantRef -// ---------------------------------------------------------------------------- - -bool IR_chillConstantRef::operator==(const IR_Ref &that) const { - if (typeid(*this) != typeid(that)) - return false; - - const IR_chillConstantRef *l_that = static_cast(&that); - - if (this->type_ != l_that->type_) - return false; - - if (this->type_ == IR_CONSTANT_INT) - return this->i_ == l_that->i_; - else - return this->f_ == l_that->f_; -} - - -omega::CG_outputRepr *IR_chillConstantRef::convert() { - //assert(astContext_ != NULL); - if (type_ == IR_CONSTANT_INT) { - - fprintf(stderr, "IR_chillConstantRef::convert() unimplemented\n"); - exit(-1); - - // TODO - /* - BuiltinType *bint = new BuiltinType(BuiltinType::Int); - IntegerLiteral *ilit = new (astContext_)IntegerLiteral(*astContext_, llvm::APInt(32, i_), bint->desugar(), SourceLocation()); - omega::CG_chillRepr *result = new omega::CG_chillRepr(ilit); - delete this; - return result; - */ - } else - throw chill::error::ir("constant type not supported"); -} - - -IR_Ref *IR_chillConstantRef::clone() const { - if (type_ == IR_CONSTANT_INT) - return new IR_chillConstantRef(ir_, i_); - else if (type_ == IR_CONSTANT_FLOAT) - return new IR_chillConstantRef(ir_, f_); - else - throw chill::error::ir("constant type not supported"); -} - -// ---------------------------------------------------------------------------- -// Class: IR_chillScalarRef -// ---------------------------------------------------------------------------- - -bool IR_chillScalarRef::is_write() const { - return op_pos_ == OP_DEST; // 2 other alternatives: OP_UNKNOWN, OP_SRC -} - - -IR_ScalarSymbol *IR_chillScalarRef::symbol() const { - chillAST_VarDecl *vd = NULL; - if (chillvd) vd = chillvd; - return new IR_chillScalarSymbol(ir_, vd); -} - - -bool IR_chillScalarRef::operator==(const IR_Ref &that) const { - if (typeid(*this) != typeid(that)) - return false; - - const IR_chillScalarRef *l_that = static_cast(&that); - - return this->chillvd == l_that->chillvd; -} - - -omega::CG_outputRepr *IR_chillScalarRef::convert() { - if (!dre) CHILL_ERROR("IR_chillScalarRef::convert() CLANG SCALAR REF has no dre\n"); - omega::CG_chillRepr *result = new omega::CG_chillRepr(dre); - delete this; - return result; -} - -IR_Ref *IR_chillScalarRef::clone() const { - if (dre) return new IR_chillScalarRef(ir_, dre); - return new IR_chillScalarRef(ir_, chillvd); -} - - -// ---------------------------------------------------------------------------- -// Class: IR_chillArrayRef -// ---------------------------------------------------------------------------- - -bool IR_chillArrayRef::is_write() const { - return (iswrite); // TODO -} - - -// TODO -omega::CG_outputRepr *IR_chillArrayRef::index(int dim) const { - return new omega::CG_chillRepr(chillASE->getIndex(dim)); -} - - -IR_ArraySymbol *IR_chillArrayRef::symbol() const { - chillAST_Node *mb = chillASE->multibase(); - chillAST_VarDecl *vd = (chillAST_VarDecl *) mb; - IR_ArraySymbol *AS = new IR_chillArraySymbol(ir_, vd); - return AS; -/* - chillAST_Node *b = chillASE->base; - fprintf(stderr, "base of type %s\n", b->getTypeString()); - //b->print(); printf("\n"); fflush(stdout); - if (b->getType() == CHILLAST_NODE_IMPLICITCASTEXPR) { - b = ((chillAST_ImplicitCastExpr*)b)->subexpr; - fprintf(stderr, "base of type %s\n", b->getTypeString()); - } - - if (b->getType() == CHILLAST_NODE_DECLREFEXPR) { - if (NULL == ((chillAST_DeclRefExpr*)b)->decl) { - fprintf(stderr, "IR_chillArrayRef::symbol() var decl = 0x%x\n", ((chillAST_DeclRefExpr*)b)->decl); - exit(-1); - } - return new IR_chillArraySymbol(ir_, ((chillAST_DeclRefExpr*)b)->decl); // -> decl? - } - if (b->getType() == CHILLAST_NODE_ARRAYSUBSCRIPTEXPR) { // multidimensional array - return ( - } - fprintf(stderr, "IR_chillArrayRef::symbol() can't handle\n"); - fprintf(stderr, "base of type %s\n", b->getTypeString()); - exit(-1); - return NULL; -*/ -} - - -bool IR_chillArrayRef::operator!=(const IR_Ref &that) const { - bool op = (*this) == that; // opposite - return !op; -} - -bool IR_chillArrayRef::operator==(const IR_Ref &that) const { - const IR_chillArrayRef *l_that = static_cast(&that); - const chillAST_ArraySubscriptExpr *thatASE = l_that->chillASE; - return (*chillASE) == (*thatASE); - /* - - if (typeid(*this) != typeid(that)) - return false; - - const IR_chillArrayRef *l_that = static_cast(&that); - - return this->as_ == l_that->as_; - */ -} - - -omega::CG_outputRepr *IR_chillArrayRef::convert() { - CG_chillRepr *result = new CG_chillRepr(chillASE->clone()); -// omega::CG_chillRepr *temp = new omega::CG_chillRepr(static_cast(this->as_)); -// omega::CG_outputRepr *result = temp->clone(); - delete this; - return result; -} - - -IR_Ref *IR_chillArrayRef::clone() const { - return new IR_chillArrayRef(ir_, chillASE, iswrite); -} - - -// ---------------------------------------------------------------------------- -// Class: IR_chillLoop -// ---------------------------------------------------------------------------- -IR_chillLoop::IR_chillLoop(const IR_Code *ir, clang::ForStmt *tf) { - CHILL_ERROR("you lose\n"); - exit(-1); -}; - -IR_chillLoop::IR_chillLoop(const IR_Code *ir, chillAST_ForStmt *achillforstmt) { - CHILL_DEBUG_BEGIN - fprintf(stderr, "loop is:\n"); - achillforstmt->print(); - CHILL_DEBUG_END - - ir_ = ir; - chillforstmt = achillforstmt; - - chillAST_BinaryOperator *init = (chillAST_BinaryOperator *) chillforstmt->getInit(); - chillAST_BinaryOperator *cond = (chillAST_BinaryOperator *) chillforstmt->getCond(); - // check to be sure (assert) - if (!init->isAssignmentOp() || !cond->isComparisonOp()) { - CHILL_ERROR("malformed loop init or cond:\n"); - achillforstmt->print(); - exit(-1); - } - - chilllowerbound = init->getRHS(); - chillupperbound = cond->getRHS(); - conditionoperator = achillforstmt->conditionoperator; - - chillAST_Node *inc = chillforstmt->getInc(); - // check the increment - if (inc->getType() == CHILLAST_NODE_UNARYOPERATOR) { - if (!strcmp(((chillAST_UnaryOperator *) inc)->op, "++")) step_size_ = 1; - else step_size_ = -1; - } else if (inc->getType() == CHILLAST_NODE_BINARYOPERATOR) { - int beets = false; // slang - chillAST_BinaryOperator *bop = (chillAST_BinaryOperator *) inc; - if (bop->isAssignmentOp()) { // I=I+1 or similar - chillAST_Node *rhs = bop->getRHS(); // (I+1) - // TODO looks like this will fail for I=1+I or I=J+1 etc. do more checking - - char *assop = bop->getOp(); - if (!strcmp(assop, "+=") || !strcmp(assop, "-=")) { - chillAST_Node *stride = rhs; - //fprintf(stderr, "stride is of type %s\n", stride->getTypeString()); - if (stride->isIntegerLiteral()) { - int val = ((chillAST_IntegerLiteral *) stride)->value; - if (!strcmp(assop, "+=")) step_size_ = val; - else if (!strcmp(assop, "-=")) step_size_ = -val; - else beets = true; - } else beets = true; // += or -= but not constant stride - } else if (rhs->isBinaryOperator()) { - chillAST_BinaryOperator *binoprhs = (chillAST_BinaryOperator *) rhs; - chillAST_Node *intlit = binoprhs->getRHS(); - if (intlit->isIntegerLiteral()) { - int val = ((chillAST_IntegerLiteral *) intlit)->value; - if (!strcmp(binoprhs->getOp(), "+")) step_size_ = val; - else if (!strcmp(binoprhs->getOp(), "-")) step_size_ = -val; - else beets = true; - } else beets = true; - } else beets = true; - } else beets = true; - - if (beets) { - CHILL_ERROR("malformed loop increment (or more likely unhandled case)\n"); - inc->print(); - exit(-1); - } - } // binary operator - else { - CHILL_ERROR("IR_chillLoop constructor, unhandled loop increment\n"); - inc->print(); - exit(-1); - } - //inc->print(0, stderr);fprintf(stderr, "\n"); - - chillAST_DeclRefExpr *dre = (chillAST_DeclRefExpr *) init->getLHS(); - if (!dre->isDeclRefExpr()) { - CHILL_DEBUG_PRINT("malformed loop init.\n"); - init->print(); - } - - chillindex = dre; // the loop index variable - - //fprintf(stderr, "\n\nindex is "); dre->print(0, stderr); fprintf(stderr, "\n"); - //fprintf(stderr, "init is "); - //chilllowerbound->print(0, stderr); fprintf(stderr, "\n"); - //fprintf(stderr, "condition is %s ", "<"); - //chillupperbound->print(0, stderr); fprintf(stderr, "\n"); - //fprintf(stderr, "step size is %d\n\n", step_size_) ; - - chillbody = achillforstmt->getBody(); - - CHILL_DEBUG_PRINT("IR_xxxxLoop::IR_xxxxLoop() DONE\n"); -} - - -omega::CG_outputRepr *IR_chillLoop::lower_bound() const { - CHILL_DEBUG_PRINT("IR_xxxxLoop::lower_bound()\n"); - return new omega::CG_chillRepr(chilllowerbound); -} - -omega::CG_outputRepr *IR_chillLoop::upper_bound() const { - CHILL_DEBUG_PRINT("IR_xxxxLoop::upper_bound()\n"); - return new omega::CG_chillRepr(chillupperbound); -} - -IR_Block *IR_chillLoop::body() const { - CHILL_DEBUG_PRINT("IR_xxxxLoop::body()\n"); - //assert(isa(tf_->getBody())); - //fprintf(stderr, "returning a clangBLOCK corresponding to the body of the loop\n"); - //fprintf(stderr, "body type %s\n", chillbody->getTypeString()); - return new IR_chillBlock(ir_, chillbody); // static_cast(tf_->getBody())); -} - -IR_Control *IR_chillLoop::clone() const { - CHILL_DEBUG_PRINT("IR_xxxxLoop::clone()\n"); - //chillforstmt->print(); fflush(stdout); - return new IR_chillLoop(ir_, chillforstmt); -} - -IR_CONDITION_TYPE IR_chillLoop::stop_cond() const { - chillAST_BinaryOperator *loopcondition = (chillAST_BinaryOperator *) chillupperbound; - CHILL_DEBUG_PRINT("IR_xxxxLoop::stop_cond()\n"); - return conditionoperator; -} - -IR_Block *IR_chillLoop::convert() { // convert the loop to a block - CHILL_DEBUG_PRINT("IR_xxxxLoop::convert() maybe \n"); - return new IR_chillBlock(ir_, chillbody); // ?? - return NULL; -} - -void IR_chillLoop::dump() const { - CHILL_ERROR("TODO: IR_chillLoop::dump()\n"); - exit(-1); -} - - -// ---------------------------------------------------------------------------- -// Class: IR_chillBlock -// ---------------------------------------------------------------------------- -omega::CG_outputRepr *IR_chillBlock::original() const { - CHILL_ERROR("IR_xxxxBlock::original() TODO \n"); - exit(-1); - return NULL; -} - - -omega::CG_outputRepr *IR_chillBlock::extract() const { - // if the block refers to a compound statement, return the next level - // of statements ; otherwise just return a repr of the statements - omega::CG_chillRepr *OR; - CHILL_DEBUG_PRINT("adding a statement from IR_chillBlock::extract()\n"); - OR = new omega::CG_chillRepr(); // empty of statements - for (int i = 0; i < statements.size(); i++) OR->addStatement(statements[i]); - CHILL_DEBUG_PRINT("IR_xxxxBlock::extract() LEAVING\n"); - return OR; -} - -IR_Control *IR_chillBlock::clone() const { - CHILL_DEBUG_PRINT("IR_xxxxBlock::clone()\n"); - return new IR_chillBlock(this); // shallow copy ? -} - -void IR_chillBlock::dump() const { - CHILL_DEBUG_PRINT("IR_chillBlock::dump() TODO\n"); - return; -} - -//StmtList -vector IR_chillBlock::getStmtList() const { - CHILL_DEBUG_PRINT("IR_xxxxBlock::getStmtList()\n"); - return statements; // ?? -} - - -void IR_chillBlock::addStatement(chillAST_Node *s) { - statements.push_back(s); -} - -class NULLASTConsumer : public ASTConsumer { -}; - - -void findmanually(chillAST_Node *node, char *procname, std::vector &procs) { - - if (node->getType() == CHILLAST_NODE_FUNCTIONDECL) { - char *name = ((chillAST_FunctionDecl *) node)->functionName; - if (!strcmp(name, procname)) { - procs.push_back(node); - // quit recursing. probably not correct in some horrible case - return; - } - } - - - // this is where the children can be used effectively. - // we don't really care what kind of node we're at. We just check the node itself - // and then its children is needed. - - int numc = node->getNumChildren(); - - for (int i = 0; i < numc; i++) - findmanually(node->getChild(i), procname, procs); - return; -} - -// ---------------------------------------------------------------------------- -// Class: IR_clangCode_Global_Init -// ---------------------------------------------------------------------------- - -IR_clangCode_Global_Init *IR_clangCode_Global_Init::pinstance = 0; - - -IR_clangCode_Global_Init *IR_clangCode_Global_Init::Instance(char **argv) { - if (pinstance == 0) { - // this is the only way to create an IR_clangCode_Global_Init - pinstance = new IR_clangCode_Global_Init; - pinstance->ClangCompiler = new aClangCompiler(argv[1]); - - } - return pinstance; -} - - -aClangCompiler::aClangCompiler(char *filename) { - SourceFileName = strdup(filename); - - // Arguments to pass to the clang frontend - std::vector args; - args.push_back(strdup(filename)); - - // The compiler invocation needs a DiagnosticsEngine so it can report problems - diagnosticOptions = new DiagnosticOptions(); // private member of aClangCompiler - - pTextDiagnosticPrinter = new clang::TextDiagnosticPrinter(llvm::errs(), - diagnosticOptions); // private member of aClangCompiler - diagnosticsEngine = new clang::DiagnosticsEngine(diagID, diagnosticOptions, pTextDiagnosticPrinter); - - // Create the compiler invocation - // This class is designed to represent an abstract "invocation" of the compiler, - // including data such as the include paths, the code generation options, - // the warning flags, and so on. - std::unique_ptr CI(new clang::CompilerInvocation()); - clang::CompilerInvocation::CreateFromArgs(*CI, &args[0], &args[0] + args.size(), *diagnosticsEngine); - // Create the compiler instance - Clang = new clang::CompilerInstance(); // TODO should have a better name ClangCompilerInstance - - - // Get ready to report problems - Clang->createDiagnostics(nullptr, true); - //Clang.createDiagnostics(0, 0); - - - targetOptions = std::make_shared(); - targetOptions->Triple = llvm::sys::getDefaultTargetTriple(); - - TargetInfo *pti = TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), targetOptions); - - Clang->setTarget(pti); - Clang->createFileManager(); - FileManager &FileMgr = Clang->getFileManager(); - fileManager = &FileMgr; - Clang->createSourceManager(FileMgr); - SourceManager &SourceMgr = Clang->getSourceManager(); - sourceManager = &SourceMgr; // ?? aclangcompiler copy - globalSRCMAN = &SourceMgr; // TODO global bad - - Clang->setInvocation(CI.get()); // Replace the current invocation - - Clang->createPreprocessor(TU_Complete); - - Clang->createASTContext(); // needs preprocessor - astContext_ = &Clang->getASTContext(); - const FileEntry *FileIn = FileMgr.getFile(filename); // needs preprocessor - SourceMgr.setMainFileID(SourceMgr.createFileID(FileIn, clang::SourceLocation(), clang::SrcMgr::C_User)); - Clang->getDiagnosticClient().BeginSourceFile(Clang->getLangOpts(), &Clang->getPreprocessor()); - - NULLASTConsumer TheConsumer; // must pass a consumer in to ParseAST(). This one does nothing - CHILL_DEBUG_PRINT("actually parsing file %s using clang\n", filename); - ParseAST(Clang->getPreprocessor(), &TheConsumer, Clang->getASTContext()); - // Translation Unit is contents of a file - TranslationUnitDecl *TUD = astContext_->getTranslationUnitDecl(); - // create another AST, very similar to the clang AST but not written by idiots - CHILL_DEBUG_PRINT("converting entire clang AST into chill AST (ir_clang.cc)\n"); - chillAST_Node *wholefile = unwrap(ConvertTranslationUnit(TUD, filename)); - entire_file_AST = (chillAST_SourceFile *) wholefile; - astContext_ = &Clang->getASTContext(); -} - - -chillAST_FunctionDecl *aClangCompiler::findprocedurebyname(char *procname) { - - //fprintf(stderr, "searching through files in the clang AST\n\n"); - //fprintf(stderr, "astContext_ 0x%x\n", astContext_); - - std::vector procs; - findmanually(entire_file_AST, procname, procs); - - //fprintf(stderr, "procs has %d members\n", procs.size()); - - if (procs.size() == 0) { - CHILL_ERROR("could not find function named '%s' in AST from file %s\n", procname, SourceFileName); - exit(-1); - } - - if (procs.size() > 1) { - CHILL_ERROR("oddly, found %d functions named '%s' in AST from file %s\n", procs.size(), procname, SourceFileName); - CHILL_ERROR("I am unsure what to do\n"); - exit(-1); - } - - CHILL_DEBUG_PRINT("found the procedure named %s\n", procname); - return (chillAST_FunctionDecl *) procs[0]; - -} - - -#ifdef NOPE -IR_clangCode_Global_Init::IR_clangCode_Global_Init(char *filename , clang::FileSystemOptions fso ) : - fileManager(fso) // , headerSearch( headerSearchOptions, fileManager, diagengine, languageOptions, pTargetInfo ) -{ - /* CLANG Initialization */ - diagnosticsEngine = new clang::DiagnosticsEngine( const IntrusiveRefCntPtr &Diags, - diagnosticOptionsnsa utah - ) ; // DiagnosticConsumer *client = 0, bool ShouldOwnClient = true) - pTextDiagnosticPrinter = new clang::TextDiagnosticPrinter(llvm::outs(), diagnosticOptions); - diagnostic = new clang::Diagnostic(pTextDiagnosticPrinter); - sourceManager = new clang::SourceManager(*diagnostic); - - // FIXME - - // -- Platform Specific Code lives here - // This depends on A) that you're running linux and - // B) that you have the same GCC LIBs installed that - // I do. - // Search through Clang itself for something like this, - // go on, you won't find it. The reason why is Clang - // has its own versions of std* which are installed under - // /usr/local/lib/clang//include/ - // See somewhere around Driver.cpp:77 to see Clang adding - // its version of the headers to its include path. - /*headerSearchOptions.AddPath("/usr/include/linux", clang::frontend::Angled, false, false, false); - headerSearchOptions.AddPath("/usr/include/c++/4.3/tr1", clang::frontend::Angled, false, false, false); - headerSearchOptions.AddPath("/usr/include/c++/4.3", clang::frontend::Angled, false, false, false);*/ - // -- End of Platform Specific Code - - targetOptions.Triple = llvm::sys::getHostTriple(); - pTargetInfo = clang::TargetInfo::CreateTargetInfo(*diagnostic, targetOptions); - clang::ApplyHeaderSearchOptions( headerSearch, headerSearchOptions, languageOptions, pTargetInfo->getTriple()); - preprocessor = new clang::Preprocessor(*diagnostic, languageOptions, *pTargetInfo, *sourceManager, headerSearch); - clang::InitializePreprocessor(*preprocessor, preprocessorOptions, headerSearchOptions, frontendOptions); - const clang::FileEntry *pFile = fileManager.getFile(filename); - sourceManager->createMainFileID(pFile); - //preprocessor.EnterMainSourceFile(); - - clang::TargetInfo &targetInfo = *pTargetInfo; - - idTable = new clang::IdentifierTable(languageOptions); - - builtinContext = new clang::Builtin::Context(targetInfo); - astContext_ = new clang::ASTContext(languageOptions, *sourceManager, targetInfo, *idTable, selTable, *builtinContext, 0); - astConsumer_ = new Chill_ASTConsumer(); - clang::Sema sema(*preprocessor, *astContext_, *astConsumer_); - sema.Initialize(); - clang::ParseAST(*preprocessor, astConsumer_, *astContext_); -} -#endif - - -IR_clangCode_Global_Init::~IR_clangCode_Global_Init() { - /* - delete pTextDiagnosticPrinter; - delete diagnostic; - delete sourceManager; - delete preprocessor; - delete idTable; - delete builtinContext; - delete astContext_; - delete astConsumer_; - */ -} - - - -// ---------------------------------------------------------------------------- -// Class: IR_clangCode -// ---------------------------------------------------------------------------- - -IR_clangCode::IR_clangCode(const char *filename, const char *proc_name, const char *dest_name) : IR_clangCode(filename, - proc_name) { - outfilename = strdup(dest_name); -} -IR_clangCode::IR_clangCode(const char *fname, const char *proc_name) : IR_Code() { - CHILL_DEBUG_PRINT("IR_xxxxCode::IR_xxxxCode()\n"); - //fprintf(stderr, "IR_clangCode::IR_clangCode( filename %s, procedure %s )\n", filename, proc_name); - - filename = strdup(fname); // filename is internal to IR_clangCode - procedurename = strdup(proc_name); - outfilename = NULL; - - int argc = 2; - char *argv[2]; - argv[0] = strdup("chill"); - argv[1] = strdup(filename); - - // use clang to parse the input file ? (or is that already done?) - //fprintf(stderr, "IR_clangCode::IR_clangCode(), parsing input file %s\n", argv[1]); - - // this causes opening and parsing of the file. - // this is the only call to Instance that has an argument list or file name - IR_clangCode_Global_Init *pInstance = IR_clangCode_Global_Init::Instance(argv); - - if (pInstance) { - - aClangCompiler *Clang = pInstance->ClangCompiler; - //fprintf(stderr, "Clang is 0x%x\n", Clang); - - //fprintf(stderr, "want to get pointer to clang ast for procedure %s\n", proc_name); - pInstance->setCurrentFunction(NULL); // we have no function AST yet - - entire_file_AST = Clang->entire_file_AST; // ugly that same name, different classes - chillAST_FunctionDecl *localFD = Clang->findprocedurebyname(strdup(proc_name)); // stored locally - //fprintf(stderr, "back from findprocedurebyname( %s )\n", proc_name ); - //localFD->print(); - - pInstance->setCurrentFunction(localFD); - - CHILL_DEBUG_BEGIN - fprintf(stderr, "Dumping AST for localFD\n"); - localFD->dump(); - CHILL_DEBUG_END - - CHILL_DEBUG_PRINT("calling new CG_chillBuilder() umwut?\n"); - ocg_ = new omega::CG_chillBuilder(localFD->getSourceFile(),localFD); // ocg == omega code gen - chillfunc = localFD; - - } - - CHILL_DEBUG_PRINT("returning after reading source file and finding function\n\n"); - - //chillfunc->dump( 0, stderr); - -} - - -IR_clangCode::~IR_clangCode() { - CHILL_DEBUG_PRINT("output happening as part of the destructor !!\n"); - - chillfunc->constantFold(); - - chillfunc->cleanUpVarDecls(); - - // TODO should output the entire file, not just the function we're working on - chillAST_SourceFile *src = chillfunc->getSourceFile(); - if (src) { - CHILL_DEBUG_BEGIN - src->dump(); - CHILL_DEBUG_END - if (src->isSourceFile()) src->printToFile(outfilename); - } -} - - -//TODO -IR_ScalarSymbol *IR_clangCode::CreateScalarSymbol(const IR_Symbol *sym, int i) { - if (typeid(*sym) == typeid(IR_chillScalarSymbol)) { // should be the case ??? - fprintf(stderr, "IR_xxxxCode::CreateScalarSymbol() from a scalar symbol\n"); - const IR_chillScalarSymbol *CSS = (IR_chillScalarSymbol *) sym; - chillAST_VarDecl *vd = CSS->chillvd; - - // do we have to check to see if it's already there? - VariableDeclarations.push_back(vd); - chillAST_Node *bod = chillfunc->getBody(); // always a compoundStmt ?? - bod->insertChild(0, vd); - fprintf(stderr, "returning ... really\n"); - return new IR_chillScalarSymbol(this, CSS->chillvd); // CSS->clone(); - } - - if (typeid(*sym) == typeid(IR_chillArraySymbol)) { - fprintf(stderr, "IR_xxxxCode::CreateScalarSymbol() from an array symbol?\n"); - const IR_chillArraySymbol *CAS = (IR_chillArraySymbol *) sym; - - chillAST_VarDecl *vd = CAS->chillvd; - fflush(stdout); - - // figure out the base type (probably float) of the array - char *basetype = vd->underlyingtype; - fprintf(stderr, "scalar will be of type SgType%s\n", basetype); - - char tmpname[128]; - sprintf(tmpname, "newVariable%i\0", vd->chill_scalar_counter++); - chillAST_VarDecl *scalarvd = new chillAST_VarDecl(basetype, tmpname, "", NULL); // TODO parent - scalarvd->print(); - printf("\n"); - fflush(stdout); - - fprintf(stderr, "VarDecl has parent that is a NULL\n"); - - return (IR_ScalarSymbol *) (new IR_chillScalarSymbol(this, scalarvd)); // CSS->clone(); - } - - fprintf(stderr, - "IR_clangCode::CreateScalarSymbol(), passed a sym that is not a clang scalar symbol OR an array symbol???\n"); - int *n = NULL; - n[0] = 1; - exit(-1); - return NULL; -} - - -IR_ArraySymbol * -IR_clangCode::CreateArraySymbol(const IR_Symbol *sym, std::vector &size, int i) { - fprintf(stderr, "IR_xxxxCode::CreateArraySymbol()\n"); - - // build a new array name - char namestring[128]; - - sprintf(namestring, "_P%d\0", entire_file_AST->chill_array_counter++); - fprintf(stderr, "creating Array %s\n", namestring); - - char arraypart[100]; - char *s = &arraypart[0]; - - for (int i = 0; i < size.size(); i++) { - omega::CG_outputRepr *OR = size[i]; - CG_chillRepr *CR = (CG_chillRepr *) OR; - //fprintf(stderr, "%d chillnodes\n", CR->chillnodes.size()); - - // this SHOULD be 1 chillnode of type IntegerLiteral (per dimension) - int numnodes = CR->chillnodes.size(); - if (1 != numnodes) { - fprintf(stderr, - "IR_clangCode::CreateArraySymbol() array dimension %d has %d chillnodes\n", - i, numnodes); - exit(-1); - } - - chillAST_Node *nodezero = CR->chillnodes[0]; - if (!nodezero->isIntegerLiteral()) { - fprintf(stderr, "IR_clangCode::CreateArraySymbol() array dimension %d not an IntegerLiteral\n", i); - exit(-1); - } - - chillAST_IntegerLiteral *IL = (chillAST_IntegerLiteral *) nodezero; - int val = IL->value; - sprintf(s, "[%d]\0", val); - s = &arraypart[strlen(arraypart)]; - } - //fprintf(stderr, "arraypart '%s'\n", arraypart); - - chillAST_VarDecl *vd = new chillAST_VarDecl("float", namestring, arraypart, NULL); // todo type from sym - - // put decl in some symbol table - VariableDeclarations.push_back(vd); - // insert decl in the IR_code body - chillAST_Node *bod = chillfunc->getBody(); // always a compoundStmt ?? - bod->insertChild(0, vd); - - return new IR_chillArraySymbol(this, vd); -} - -// TODO -std::vector IR_clangCode::FindScalarRef(const omega::CG_outputRepr *repr) const { - std::vector scalars; - - const omega::CG_chillRepr *crepr = static_cast(repr); - std::vector chillstmts = crepr->getChillCode(); - - std::vector refs; - for (int i = 0; i < chillstmts.size(); i++) { - chillstmts[i]->gatherScalarRefs(refs,false); - } - for (int i = 0; i < refs.size(); i++) { - scalars.push_back(new IR_chillScalarRef(this, refs[i])); - } - return scalars; -} - - -IR_ScalarRef *IR_clangCode::CreateScalarRef(const IR_ScalarSymbol *sym) { - IR_chillScalarRef *sr = new IR_chillScalarRef(this, new chillAST_DeclRefExpr( - ((IR_chillScalarSymbol *) sym)->chillvd)); // uses VarDecl to mak a declrefexpr - return sr; -} - -bool IR_clangCode::FromSameStmt(IR_ArrayRef *A, IR_ArrayRef *B) { - return ((IR_chillArrayRef*)A)->chillASE->findContainingStmt() == ((IR_chillArrayRef*)A)->chillASE->findContainingStmt(); -} - -IR_ArrayRef *IR_clangCode::CreateArrayRef(const IR_ArraySymbol *sym, std::vector &index) { - fprintf(stderr, "IR_clangCode::CreateArrayRef() ir_clang.cc\n"); - fprintf(stderr, "sym->n_dim() %d index.size() %d\n", sym->n_dim(), index.size()); - - int t; - if (sym->n_dim() != index.size()) { - throw std::invalid_argument("incorrect array symbol dimensionality dim != size ir_clang.cc L2359"); - } - - const IR_chillArraySymbol *c_sym = static_cast(sym); - chillAST_VarDecl *vd = c_sym->chillvd; - std::vector inds; - - for (int i = 0; i < index.size(); i++) { - CG_chillRepr *CR = (CG_chillRepr *) index[i]; - - int numnodes = CR->chillnodes.size(); - if (1 != numnodes) { - CHILL_ERROR("IR_clangCode::CreateArrayRef() array dimension %d has %d chillnodes\n", i, numnodes); - exit(-1); - } - - inds.push_back(CR->chillnodes[0]); - - /* - chillAST_Node *nodezero = CR->chillnodes[0]; - if (!nodezero->isIntegerLiteral()) { - fprintf(stderr,"IR_clangCode::CreateArrayRef() array dimension %d not an IntegerLiteral\n",i); - fprintf(stderr, "it is a %s\n", nodezero->getTypeString()); - nodezero->print(); printf("\n"); fflush(stdout); - exit(-1); - } - - chillAST_IntegerLiteral *IL = (chillAST_IntegerLiteral *)nodezero; - int val = IL->value; - inds.push_back( val ); - */ - } - - // now we've got the vardecl AND the indeces to make a chillAST that represents the array reference - // TODO Passing NULL for chillAST node? - CHILL_DEBUG_PRINT("Passed NULL as chillAST node"); - chillAST_ArraySubscriptExpr *ASE = new chillAST_ArraySubscriptExpr(vd, inds); - - auto ref = new IR_chillArrayRef(this, ASE, 0); - - return ref; -} - -// find all array references ANYWHERE in this block of code ?? -std::vector IR_clangCode::FindArrayRef(const omega::CG_outputRepr *repr) const { - //fprintf(stderr, "FindArrayRef()\n"); - std::vector arrays; - const omega::CG_chillRepr *crepr = static_cast(repr); - std::vector chillstmts = crepr->getChillCode(); - - //fprintf(stderr, "there are %d chill statements in this repr\n", chillstmts.size()); - - std::vector refs; - for (int i = 0; i < chillstmts.size(); i++) { - //fprintf(stderr, "\nchillstatement %d = ", i); chillstmts[i]->print(0, stderr); fprintf(stderr, "\n"); - chillstmts[i]->gatherArrayRefs(refs, false); - } - //fprintf(stderr, "%d total refs\n", refs.size()); - for (int i = 0; i < refs.size(); i++) { - if (refs[i]->imreadfrom) { - //fprintf(stderr, "ref[%d] going to be put in TWICE, as both read and write\n", i); - arrays.push_back(new IR_chillArrayRef(this, refs[i], 0)); // UGLY TODO dual usage of a ref in "+=" - } - arrays.push_back(new IR_chillArrayRef(this, refs[i], refs[i]->imwrittento)); // this is wrong - // we need to know whether this reference will be written, etc. - } - - /* - if(chillstmts.size() > 1) { - for(int i=0; isize(); ++i) { - omega::CG_chillRepr *r = new omega::CG_chillRepr((*tnl)[i]); - std::vector a = FindArrayRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(arrays)); - } - } else if(chillstmts.size() == 1) { - Stmt *s = (*tnl)[0]; - - if(CompoundStmt *cs = dyn_cast(s)) { - for(CompoundStmt::body_iterator bi = cs->body_begin(); bi != cs->body_end(); ++bi) { - omega::CG_chillRepr *r = new omega::CG_chillRepr(*bi); - std::vector a = FindArrayRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(arrays)); - } - } else if(ForStmt *fs = dyn_cast(s)) { - omega::CG_chillRepr *r = new omega::CG_chillRepr(fs->getBody()); - std::vector a = FindArrayRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(arrays)); - } else if(IfStmt *ifs = dyn_cast(s)) { - omega::CG_chillRepr *r = new omega::CG_chillRepr(ifs->getCond()); - std::vector a = FindArrayRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(arrays)); - r = new omega::CG_chillRepr(ifs->getThen()); - a = FindArrayRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(arrays)); - if(Stmt *s_else = ifs->getElse()) { - r = new omega::CG_chillRepr(s_else); - a = FindArrayRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(arrays)); - } - } else if(Expr *e = dyn_cast(s)) { - omega::CG_chillRepr *r = new omega::CG_chillRepr(static_cast(s)); - std::vector a = FindArrayRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(arrays)); - } else throw chill::error::ir("control structure not supported"); - } - */ -/* - else { // We have an expression - Expr *op = static_cast(repr)->GetExpression(); - if(0) { // TODO: Handle pointer reference exp. here - } else if(BinaryOperator *bop = dyn_cast(op)) { - omega::CG_chillRepr *r1 = new omega::CG_chillRepr(bop->getLHS()); - std::vector a1 = FindArrayRef(r1); - delete r1; - std::copy(a1.begin(), a1.end(), back_inserter(arrays)); - omega::CG_chillRepr *r2 = new omega::CG_chillRepr(bop->getRHS()); - std::vector a2 = FindArrayRef(r2); - delete r2; - std::copy(a2.begin(), a2.end(), back_inserter(arrays)); - } else if(UnaryOperator *uop = dyn_cast(op)) { - omega::CG_chillRepr *r1 = new omega::CG_chillRepr(uop->getSubExpr()); - std::vector a1 = FindArrayRef(r1); - delete r1; - std::copy(a1.begin(), a1.end(), back_inserter(arrays)); - } //else throw chill::error::ir("Invalid expr. type passed to FindArrayRef"); - } - */ - return arrays; -} - - -std::vector IR_clangCode::FindOneLevelControlStructure(const IR_Block *block) const { - const IR_chillBlock *CB = (const IR_chillBlock *) block; - //fprintf(stderr, "block 0x%x\n", block); - - std::vector controls; - - chillAST_Node *blockast = NULL; - int numstmts = CB->statements.size(); - bool unwrap = false; - CHILL_DEBUG_PRINT("%d statements\n", numstmts); - - if (numstmts == 0) return controls; - - else if (numstmts == 1) blockast = CB->statements[0]; // a single statement - - CHILL_DEBUG_BEGIN - for (int i = 0; i < CB->statements.size(); ++i) { - fprintf(stderr, "block's AST is of type %s\n", CB->statements[i]->getTypeString()); - CB->statements[i]->print(); - } - CHILL_DEBUG_END - - // build up a vector of "controls". - // a run of straight-line code (statements that can't cause branching) will be - // bundled up into an IR_Block - // ifs and loops will get their own entry - const std::vector *children = NULL; - if (blockast) { - if (blockast->isFunctionDecl()) { - chillAST_FunctionDecl *FD = (chillAST_FunctionDecl *) blockast; - chillAST_Node *bod = FD->getBody(); - children = bod->getChildren(); - unwrap = true; - } - if (blockast->isCompoundStmt()) { - children = blockast->getChildren(); - unwrap = true; - } - if (blockast->isForStmt()) { - controls.push_back(new IR_chillLoop(this, (chillAST_ForStmt *) blockast)); - return controls; - } - } - if (!children) - children = &(CB->statements); - - int numchildren = children->size(); - int ns; - IR_chillBlock *basicblock = new IR_chillBlock(this); // no statements - for (int i = 0; i < numchildren; i++) { - CHILLAST_NODE_TYPE typ = (*children)[i]->getType(); - if (typ == CHILLAST_NODE_LOOP) { - ns = basicblock->numstatements(); - if (ns) { - CHILL_DEBUG_PRINT("pushing a run of statements as a block\n"); - controls.push_back(basicblock); - basicblock = new IR_chillBlock(this); // start a new one - } - - CHILL_DEBUG_PRINT("pushing the loop at %d\n", i); - controls.push_back(new IR_chillLoop(this, (chillAST_ForStmt *) (*children)[i])); - } else if (typ == CHILLAST_NODE_IFSTMT ) { - ns = basicblock->numstatements(); - if (ns) { - CHILL_DEBUG_PRINT("pushing a run of statements as a block\n"); - controls.push_back(basicblock); - basicblock = new IR_chillBlock(this); // start a new one - } - CHILL_DEBUG_PRINT("pushing the if at %d\n", i); - controls.push_back(new IR_chillIf(this, (chillAST_IfStmt *) (*children)[i])); - } else - basicblock->addStatement((*children)[i]); - } // for each child - ns = basicblock->numstatements(); - if (ns != 0 && (unwrap || ns != numchildren)) - controls.push_back(basicblock); - - CHILL_DEBUG_PRINT("returning vector of %d controls\n", controls.size()); - return controls; -} - - -IR_Block *IR_clangCode::MergeNeighboringControlStructures(const std::vector &controls) const { - CHILL_DEBUG_PRINT("%d controls\n", controls.size()); - - if (controls.size() == 0) - return NULL; - - IR_chillBlock *CBlock = new IR_chillBlock(controls[0]->ir_); // the thing we're building - - std::vector statements; - chillAST_Node *parent = NULL; - for (int i = 0; i < controls.size(); i++) { - switch (controls[i]->type()) { - case IR_CONTROL_LOOP: { - CHILL_DEBUG_PRINT("control %d is IR_CONTROL_LOOP\n", i); - chillAST_ForStmt *loop = static_cast(controls[i])->chillforstmt; - if (parent == NULL) { - parent = loop->getParent(); - } else { - if (parent != loop->getParent()) { - throw chill::error::ir("controls to merge not at the same level"); - } - } - CBlock->addStatement(loop); - break; - } - case IR_CONTROL_BLOCK: { - CHILL_DEBUG_PRINT("control %d is IR_CONTROL_BLOCK\n", i); - IR_chillBlock *CB = static_cast(controls[i]); - std::vector blockstmts = CB->statements; - for (int j = 0; j < blockstmts.size(); j++) { - if (parent == NULL) { - parent = blockstmts[j]->getParent(); - } else { - if (parent != blockstmts[j]->getParent()) { - throw chill::error::ir( - "ir_clang.cc IR_clangCode::MergeNeighboringControlStructures controls to merge not at the same level"); - } - } - CBlock->addStatement(blockstmts[j]); - } - break; - } - default: - throw chill::error::ir("unrecognized control to merge"); - } - } // for each control - - return CBlock; -} - - -IR_Block *IR_clangCode::GetCode() const { // return IR_Block corresponding to current function? - //fprintf(stderr, "IR_clangCode::GetCode()\n"); - //Stmt *s = func_->getBody(); // clang statement, and clang getBody - //fprintf(stderr, "chillfunc 0x%x\n", chillfunc); - - //chillAST_Node *bod = chillfunc->getBody(); // chillAST - //fprintf(stderr, "printing the function getBody()\n"); - //fprintf(stderr, "sourceManager 0x%x\n", sourceManager); - //bod->print(); - - return new IR_chillBlock(this, chillfunc); -} - - -void IR_clangCode::ReplaceCode(IR_Control *old, omega::CG_outputRepr *repr) { - CG_chillRepr *chillrepr = (CG_chillRepr *) repr; - std::vector newcode = chillrepr->getChillCode(); - int numnew = newcode.size(); - struct IR_chillLoop *cloop; - std::vector olddecls; - chillfunc->gatherVarDecls(olddecls); - std::vector decls; - for (int i = 0; i < numnew; i++) - newcode[i]->gatherVarUsage(decls); - - for (int i = 0; i < decls.size(); i++) { - int inthere = 0; - for (int j = 0; j < VariableDeclarations.size(); j++) - if (VariableDeclarations[j] == decls[i]) - inthere = 1; - for (int j = 0; j < olddecls.size(); j++) { - if (decls[i] == olddecls[j]) - inthere = 1; - if (!strcmp(decls[i]->varname, olddecls[j]->varname)) - if (!strcmp(decls[i]->arraypart, olddecls[j]->arraypart)) - inthere = 1; - } - if (!inthere) { - chillfunc->getBody()->insertChild(0, decls[i]); - olddecls.push_back(decls[i]); - } - } - - chillAST_Node *par; - switch (old->type()) { - case IR_CONTROL_LOOP: { - cloop = (struct IR_chillLoop *) old; - chillAST_ForStmt *forstmt = cloop->chillforstmt; - - par = forstmt->getParent(); - if (!par) { - CHILL_ERROR("old parent was NULL\n"); - CHILL_ERROR("ir_clang.cc that will not work very well.\n"); - exit(-1); - } - - CHILL_DEBUG_BEGIN - fprintf(stderr, "\nold parent was\n\n{\n"); - par->print(); - fprintf(stderr, "\n}\n"); - CHILL_DEBUG_END - - std::vector *oldparentcode = par->getChildren(); // probably only works for compoundstmts - - // find loop in the parent - int numstatements = oldparentcode->size(); - int index = par->findChild(forstmt); - if (index < 0) { - CHILL_ERROR("can't find the loop in its parent\n"); - exit(-1); - } - // insert the new code - par->setChild(index, newcode[0]); // overwrite old stmt - // do we need to update the IR_cloop? - cloop->chillforstmt = (chillAST_ForStmt *) newcode[0]; // ?? DFL - - if (numnew > 1) { - // add the rest of the new statements - CHILL_DEBUG_BEGIN - for (int i = 1; i < numnew; i++) { - fprintf(stderr, "inserting \n"); - newcode[i]->print(0, stderr); - } - CHILL_DEBUG_END - for (int i = 1; i < numnew; i++) - par->insertChild(index + i, newcode[i]); // sets parent - } - - // TODO add in (insert) variable declarations that go with the new loops - - fflush(stdout); - } - break; - case IR_CONTROL_BLOCK: { - CHILL_ERROR("old is IR_CONTROL_BLOCK\n"); - par = ((IR_chillBlock*)old)->statements[0]->getParent(); - if (!par) { - CHILL_ERROR("old parent was NULL\n"); - CHILL_ERROR("ir_clang.cc that will not work very well.\n"); - exit(-1); - } - IR_chillBlock *cblock = (struct IR_chillBlock *) old; - std::vector *oldparentcode = par->getChildren(); // probably only works for compoundstmts - int index = par->findChild(cblock->statements[0]); - for (int i = 0;inumstatements();++i) // delete all current statements - par->removeChild(par->findChild(cblock->statements[i])); - for (int i = 0; i < numnew; i++) - par->insertChild(index + i, newcode[i]); // insert New child - // TODO add in (insert) variable declarations that go with the new loops - break; - } - default: - throw chill::error::ir("control structure to be replaced not supported"); - break; - } - - fflush(stdout); - CHILL_DEBUG_BEGIN - fprintf(stderr, "new parent2 is\n\n{\n"); - std::vector *newparentcode = par->getChildren(); - for (int i = 0; i < newparentcode->size(); i++) { - (*newparentcode)[i]->print(); - } - fprintf(stderr, "}\n"); - CHILL_DEBUG_END - - -} - - -void IR_clangCode::ReplaceExpression(IR_Ref *old, omega::CG_outputRepr *repr) { - if (typeid(*old) == typeid(IR_chillArrayRef)) { - IR_chillArrayRef *CAR = (IR_chillArrayRef *) old; - chillAST_ArraySubscriptExpr *CASE = CAR->chillASE; - - omega::CG_chillRepr *crepr = (omega::CG_chillRepr *) repr; - if (crepr->chillnodes.size() != 1) { - CHILL_ERROR("IR_clangCode::ReplaceExpression(), replacing with %d chillnodes???\n"); - //exit(-1); - } - - chillAST_Node *newthing = crepr->chillnodes[0]; - - if (!CASE->getParent()) { - CHILL_ERROR("IR_clangCode::ReplaceExpression() old has no parent ??\n"); - exit(-1); - } - - CASE->getParent()->replaceChild(CASE, newthing); - - } else if (typeid(*old) == typeid(IR_chillScalarRef)) { - fprintf(stderr, "IR_clangCode::ReplaceExpression() IR_chillScalarRef unhandled\n"); - } else { - fprintf(stderr, "UNKNOWN KIND OF REF\n"); - exit(-1); - } - - delete old; -} - - -// TODO -IR_CONDITION_TYPE IR_clangCode::QueryBooleanExpOperation(const omega::CG_outputRepr *repr) const { - return IR_COND_UNKNOWN; -} - - -IR_OPERATION_TYPE IR_clangCode::QueryExpOperation(const omega::CG_outputRepr *repr) const { - CG_chillRepr *crepr = (CG_chillRepr *) repr; - chillAST_Node *node = crepr->chillnodes[0]; - // really need to be more rigorous than this hack // TODO - if (node->isImplicitCastExpr()) node = ((chillAST_ImplicitCastExpr *) node)->getSubExpr(); - if (node->isCStyleCastExpr()) node = ((chillAST_CStyleCastExpr *) node)->getSubExpr(); - if (node->isParenExpr()) node = ((chillAST_ParenExpr *) node)->getSubExpr(); - - if (node->isIntegerLiteral() || node->isFloatingLiteral()) return IR_OP_CONSTANT; - else if (node->isBinaryOperator() || node->isUnaryOperator()) { - char *opstring; - if (node->isBinaryOperator()) - opstring = ((chillAST_BinaryOperator *) node)->op; // TODO enum - else - opstring = ((chillAST_UnaryOperator *) node)->op; // TODO enum - - if (!strcmp(opstring, "+")) return IR_OP_PLUS; - if (!strcmp(opstring, "-")) return IR_OP_MINUS; - if (!strcmp(opstring, "*")) return IR_OP_MULTIPLY; - if (!strcmp(opstring, "/")) return IR_OP_DIVIDE; - if (!strcmp(opstring, "=")) return IR_OP_ASSIGNMENT; - - CHILL_ERROR("UNHANDLED Binary(or Unary)Operator op type (%s)\n", opstring); - exit(-1); - } else if (node->isDeclRefExpr()) return IR_OP_VARIABLE; // ?? - //else if (node->is ) return something; - else { - CHILL_ERROR("IR_clangCode::QueryExpOperation() UNHANDLED NODE TYPE %s\n", node->getTypeString()); - exit(-1); - } - - /* CLANG - Expr *e = static_cast(repr)->GetExpression(); - if(isa(e) || isa(e)) return IR_OP_CONSTANT; - else if(isa(e)) return IR_OP_VARIABLE; - else if(BinaryOperator *bop = dyn_cast(e)) { - switch(bop->getOpcode()) { - case BO_Assign: return IR_OP_ASSIGNMENT; - case BO_Add: return IR_OP_PLUS; - case BO_Sub: return IR_OP_MINUS; - case BO_Mul: return IR_OP_MULTIPLY; - case BO_Div: return IR_OP_DIVIDE; - default: return IR_OP_UNKNOWN; - } - } else if(UnaryOperator *uop = dyn_cast(e)) { - switch(uop->getOpcode()) { - case UO_Minus: return IR_OP_NEGATIVE; - case UO_Plus: return IR_OP_POSITIVE; - default: return IR_OP_UNKNOWN; - } - } else if(ConditionalOperator *cop = dyn_cast(e)) { - BinaryOperator *bop; - if(bop = dyn_cast(cop->getCond())) { - if(bop->getOpcode() == BO_GT) return IR_OP_MAX; - else if(bop->getOpcode() == BO_LT) return IR_OP_MIN; - } else return IR_OP_UNKNOWN; - - } - - else if(e == NULL) return IR_OP_NULL; - else return IR_OP_UNKNOWN; - } - END CLANG */ -} - - -std::vector IR_clangCode::QueryExpOperand(const omega::CG_outputRepr *repr) const { - //fprintf(stderr, "IR_clangCode::QueryExpOperand()\n"); - std::vector v; - - CG_chillRepr *crepr = (CG_chillRepr *) repr; - //Expr *e = static_cast(repr)->GetExpression(); wrong.. CLANG - chillAST_Node *e = crepr->chillnodes[0]; // ?? - //e->print(); printf("\n"); fflush(stdout); - - // really need to be more rigorous than this hack // TODO - if (e->isImplicitCastExpr()) e = ((chillAST_ImplicitCastExpr *) e)->getSubExpr(); - if (e->isCStyleCastExpr()) e = ((chillAST_CStyleCastExpr *) e)->getSubExpr(); - if (e->isParenExpr()) e = ((chillAST_ParenExpr *) e)->getSubExpr(); - - - //if(isa(e) || isa(e) || isa(e)) { - if (e->isIntegerLiteral() || e->isFloatingLiteral() || e->isDeclRefExpr()) { - //fprintf(stderr, "it's a constant\n"); - omega::CG_chillRepr *repr = new omega::CG_chillRepr(e); - v.push_back(repr); - //} else if(BinaryOperator *bop = dyn_cast(e)) { - } else if (e->isBinaryOperator()) { - //fprintf(stderr, "ir_clang.cc BOP TODO\n"); exit(-1); // - chillAST_BinaryOperator *bop = (chillAST_BinaryOperator *) e; - char *op = bop->op; // TODO enum for operator types - if (!strcmp(op, "=")) { - v.push_back(new omega::CG_chillRepr(bop->getRHS())); // for assign, return RHS - } else if (!strcmp(op, "+") || !strcmp(op, "-") || !strcmp(op, "*") || !strcmp(op, "/")) { - v.push_back(new omega::CG_chillRepr(bop->getLHS())); // for +*-/ return both lhs and rhs - v.push_back(new omega::CG_chillRepr(bop->getRHS())); - } else { - CHILL_ERROR("Binary Operator UNHANDLED op (%s)\n", op); - exit(-1); - } - } // BinaryOperator - else if (e->isUnaryOperator()) { - omega::CG_chillRepr *repr; - chillAST_UnaryOperator *uop = (chillAST_UnaryOperator *) e; - char *op = uop->op; // TODO enum - if (!strcmp(op, "+") || !strcmp(op, "-")) { - v.push_back(new omega::CG_chillRepr(uop->getSubExpr())); - } else { - CHILL_ERROR("ir_clang.cc IR_clangCode::QueryExpOperand() Unary Operator UNHANDLED op (%s)\n", op); - exit(-1); - } - } // unaryoperator - else { - CHILL_ERROR("UNHANDLED node type %s\n", e->getTypeString()); - exit(-1); - } - - - /* -Expr *op1, *op2; - switch(bop->getOpcode()) { - case BO_Assign: - op2 = bop->getRHS(); - repr = new omega::CG_chillRepr(op2); - v.push_back(repr); - break; - case BO_Add: - case BO_Sub: - case BO_Mul: - case BO_Div: - op1 = bop->getLHS(); - repr = new omega::CG_chillRepr(op1); - v.push_back(repr); - op2 = bop->getRHS(); - repr = new omega::CG_chillRepr(op2); - v.push_back(repr); - break; - default: - throw chill::error::ir("operation not supported"); - } - */ - //} else if(UnaryOperator *uop = dyn_cast(e)) { - //} else if(e->isUnaryOperator()) { - /* - omega::CG_chillRepr *repr; - - switch(uop->getOpcode()) { - case UO_Minus: - case UO_Plus: - op1 = uop->getSubExpr(); - repr = new omega::CG_chillRepr(op1); - v.push_back(repr); - break; - default: - throw chill::error::ir("operation not supported"); - } - */ - //} else if(ConditionalOperator *cop = dyn_cast(e)) { - //omega::CG_chillRepr *repr; - - // TODO: Handle conditional operator here - //} else throw chill::error::ir("operand type UNsupported"); - - return v; -} - -IR_Ref *IR_clangCode::Repr2Ref(const omega::CG_outputRepr *repr) const { - CG_chillRepr *crepr = (CG_chillRepr *) repr; - chillAST_Node *node = crepr->chillnodes[0]; - - if (node->isIntegerLiteral()) { - // FIXME: Not sure if it'll work in all cases (long?) - int val = ((chillAST_IntegerLiteral *) node)->value; - return new IR_chillConstantRef(this, static_cast(val)); - } else if (node->isFloatingLiteral()) { - float val = ((chillAST_FloatingLiteral *) node)->value; - return new IR_chillConstantRef(this, val); - } else if (node->isDeclRefExpr()) { - return new IR_chillScalarRef(this, (chillAST_DeclRefExpr *) node); // uses DRE - } else { - CHILL_ERROR("ir_clang.cc IR_clangCode::Repr2Ref() UNHANDLED node type %s\n", node->getTypeString()); - exit(-1); - } -} - -chillAST_NodeList* ConvertMemberExpr(clang::MemberExpr *clangME) { - chillAST_Node *base = unwrap(ConvertGenericClangAST(clangME->getBase())); - - DeclarationNameInfo memnameinfo = clangME->getMemberNameInfo(); - DeclarationName DN = memnameinfo.getName(); - const char *member = DN.getAsString().c_str(); - - chillAST_MemberExpr *ME = new chillAST_MemberExpr(base, member, clangME); - - NL_RET(ME); - -} - -omega::CG_outputRepr *IR_chillIf::condition() const { - assert( code->isIfStmt() && "If statement's code is not if statement"); - return new omega::CG_chillRepr(((chillAST_IfStmt*)code) -> getCond()); -} - -IR_Block *IR_chillIf::then_body() const { - assert( code->isIfStmt() && "If statement's code is not if statement"); - chillAST_Node* thenPart = ((chillAST_IfStmt*)code) -> getThen(); - if (thenPart) return new IR_chillBlock(ir_,thenPart); - return NULL; -} - -IR_Block *IR_chillIf::else_body() const { - assert( code->isIfStmt() && "If statement's code is not if statement"); - chillAST_Node* elsePart = ((chillAST_IfStmt*)code) -> getElse(); - if (elsePart) return new IR_chillBlock(ir_,elsePart); - return NULL; -} - -IR_Block *IR_chillIf::convert() { - const IR_Code *ir = ir_; - chillAST_Node *code = this->code; - delete this; - return new IR_chillBlock(ir,code); -} - -IR_Control *IR_chillIf::clone() const { - return new IR_chillIf(ir_,code); -} -- cgit v1.2.3-70-g09d2