summaryrefslogtreecommitdiff
path: root/include/ir_clang.hh
diff options
context:
space:
mode:
Diffstat (limited to 'include/ir_clang.hh')
-rwxr-xr-xinclude/ir_clang.hh479
1 files changed, 479 insertions, 0 deletions
diff --git a/include/ir_clang.hh b/include/ir_clang.hh
new file mode 100755
index 0000000..7c3d451
--- /dev/null
+++ b/include/ir_clang.hh
@@ -0,0 +1,479 @@
+#ifndef IR_CLANG_HH
+#define IR_CLANG_HH
+
+#include <omega.h>
+#include "ir_code.hh"
+//#include <AstInterface_CLANG.h>
+#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 "chill_ast.hh"
+
+// using namespace clang; // NEVER EVER do this in a header file
+// using namespace clang::driver; // NEVER EVER do this in a header file
+
+extern std::vector<chillAST_VarDecl *> VariableDeclarations; // a global. TODO
+
+typedef llvm::SmallVector<clang::Stmt *, 16> StmtList; // TODO delete
+
+struct IR_chillScalarSymbol: public IR_ScalarSymbol {
+ chillAST_VarDecl *chillvd;
+
+ IR_chillScalarSymbol(const IR_Code *ir, chillAST_VarDecl *vd) {
+ fprintf(stderr, "making scalar symbol %s\n", vd->varname);
+ 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 {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->lhs;
+ 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->rhs;
+ 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 {
+ //DeclRefExpr *as_;
+ //chillAST_DeclRefExpr *chillDRE;
+ chillAST_ArraySubscriptExpr* chillASE;
+ int iswrite;
+
+
+ // IR_chillArrayRef(const IR_Code *ir, DeclRefExpr *as, ParentMap *pMap = NULL) {
+ // ir_ = ir;
+ // fprintf(stderr, "new IR_chillArrayRef() CLANG ERROR\n"); exit(-1);
+ //}
+
+ IR_chillArrayRef(const IR_Code *ir, chillAST_ArraySubscriptExpr *ase, int write ) {
+ //fprintf(stderr, "IR_chillArrayRef::IR_chillArrayRef() write %d\n", write);
+ ir_ = ir;
+ chillASE = ase;
+ iswrite = write; // ase->imwrittento;
+ }
+
+ 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;
+ 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<chillAST_node *>statements;
+ chillAST_node *chillAST; // how about for now we say if there are statements, which is presumably the top level of statements from ... somewhere, otherwise the code is in chillAST
+
+ //IR_chillBlock(const IR_Code *ir, const StmtList& bDecl) : bDecl_(bDecl), cs_(NULL) {
+ // fprintf(stderr, "MISTAKE IR_chillBlock bdecl\n"); exit(-1);
+ // ir_ = ir;
+ //}
+ //IR_chillBlock(const IR_Code *ir, clang::CompoundStmt *cs) : cs_(cs) {
+ // fprintf(stderr, "MISTAKE IR_chillBlock cs\n"); exit(-1);
+ // ir_ = ir;
+ //}
+ 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] );
+ chillAST = CB->chillAST;
+ }
+
+ IR_chillBlock(const IR_Code *ir, chillAST_node *ast) {
+ ir_ = ir;
+ chillAST = ast;
+ }
+
+ IR_chillBlock(const IR_Code *ir) { // : cs_(NULL), bDecl_(NULL) {
+ chillAST = NULL;
+ ir_ = ir;
+ }
+
+
+ ~IR_chillBlock() {}
+ omega::CG_outputRepr *extract() const;
+ omega::CG_outputRepr *original() const;
+ IR_Control *clone() const;
+ //StmtList getStmtList() const;
+ std::vector<chillAST_node*> getStmtList() const;
+ int numstatements() { return statements.size(); } ;
+ void addStatement( chillAST_node* s );
+
+ void dump() const;
+};
+
+
+#ifdef NOTYET
+struct IR_clangIf: public IR_If {
+ SgNode *ti_;
+
+ IR_clangIf(const IR_Code *ir, SgNode *ti) {
+ ir_ = ir;
+ ti_ = ti;
+ }
+ ~IR_clangIf() {
+ }
+ omega::CG_outputRepr *condition() const;
+ IR_Block *then_body() const;
+ IR_Block *else_body() const;
+ IR_Block *convert();
+ IR_Control *clone() const;
+};
+#endif
+
+
+
+
+
+class aClangCompiler {
+private:
+ //Chill_ASTConsumer *astConsumer_;
+ clang::ASTContext *astContext_;
+
+ clang::DiagnosticOptions *diagnosticOptions;
+ clang::TextDiagnosticPrinter *pTextDiagnosticPrinter;
+ clang::DiagnosticIDs *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;
+ clang::TargetOptions *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;
+
+
+ chillAST_node *entire_file_AST;
+ chillAST_FunctionDecl * chillfunc; // the function we're currenly modifying
+
+ std::vector<chillAST_VarDecl> 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, char *proc_name);
+ ~IR_clangCode();
+
+ IR_ScalarSymbol *CreateScalarSymbol(const IR_Symbol *sym, int i);
+ IR_ArraySymbol *CreateArraySymbol(const IR_Symbol *sym, std::vector<omega::CG_outputRepr *> &size, int i);
+ IR_ScalarRef *CreateScalarRef(const IR_ScalarSymbol *sym);
+ IR_ArrayRef *CreateArrayRef(const IR_ArraySymbol *sym, std::vector<omega::CG_outputRepr *> &index);
+ int ArrayIndexStartAt() { return 0;} // TODO FORTRAN
+
+ std::vector<IR_ScalarRef *> FindScalarRef(const omega::CG_outputRepr *repr) const;
+ std::vector<IR_ArrayRef *> FindArrayRef(const omega::CG_outputRepr *repr) const;
+ std::vector<IR_Control *> FindOneLevelControlStructure(const IR_Block *block) const;
+ IR_Block *MergeNeighboringControlStructures(const std::vector<IR_Control *> &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<omega::CG_outputRepr *> QueryExpOperand(const omega::CG_outputRepr *repr) const;
+ IR_Ref *Repr2Ref(const omega::CG_outputRepr *) const;
+
+ friend class IR_chillArraySymbol;
+ friend class IR_chillArrayRef;
+};
+
+
+#endif