Project Stage 3 : Part 2

 This part is to cover up for the things that i may have missed in the previous stages. So i extracted both the tar zip files (spo600-gcc-pass-demo and spo600-gcc-pass-demo-2) which extracted 4 files each:


The tar file had everything I needed to modify GCC. My professor provided details about which files to change, and I updated four of them:


passes.def: Added NEXT_PASS (pass_ctyler);

tree-ctyler.cc: Contained the actual pass code.

tree-pass.h: Added extern gimple_opt_pass *make_pass_ctyler (gcc::context *ctxt);

Makefile.in: Added tree-ctyler.o to the OBJS definition.


Both zip files have same files and same code except the execute function in tree-ctyler.cc as shown below;

spo600-gcc-pass-demo:

unsigned int
pass_ctyler::execute (function *fun)
  {
    basic_block bb;

    int bb_cnt = 0, stmt_cnt = 0;

    FOR_EACH_BB_FN (bb, fun)
      {
        bb_cnt++;
        if (dump_file)
          {
            fprintf (dump_file, "===== Basic block count: %d =====\n", bb_cnt);
          }
     
        for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
          {
            gimple *g = gsi_stmt (gsi);
            stmt_cnt++;
            if (dump_file)
              {
                fprintf (dump_file, "----- Statement count: %d -----\n", stmt_cnt);
                print_gimple_stmt (dump_file, g, 0, TDF_VOPS|TDF_MEMSYMS);
              }
         }
       }

    return 0;

    if (dump_file)
      {
        fprintf (dump_file, "\n\n##### End ctyler diagnostics, start regular dump of current gimple #####\n\n\n");
      }

  }



spo600-gcc-pass-demo-2:

unsigned int
pass_ctyler::execute (function *)
  {
    struct cgraph_node *node;
    int func_cnt = 0;
   
    FOR_EACH_FUNCTION (node)
      {
        if (dump_file)
          {
            fprintf (dump_file, "=== Function %d Name '%s' ===\n", ++func_cnt, node->name() );
          }
      }

    if (dump_file)
      {
        fprintf (dump_file, "\n\n#### End ctyler diagnostics, start regular dump of current gimple ####\n\n\n");
      }

    return 0;

  }



Let's start with adding a Pass to GCC compiler. 


1. Open passes.def file

vi passes.def


2. We see that its already added NEXT_PASS (pass_ctyler);

  NEXT_PASS (pass_tsan_O0);

  NEXT_PASS (pass_sanopt);

  NEXT_PASS (pass_cleanup_eh);

  NEXT_PASS (pass_musttail);

  NEXT_PASS (pass_lower_resx);

  NEXT_PASS (pass_nrv);

  NEXT_PASS (pass_ctyler);

  NEXT_PASS (pass_gimple_isel);

  NEXT_PASS (pass_harden_conditional_branches);

  NEXT_PASS (pass_harden_compares);

  NEXT_PASS (pass_warn_access, /*early=*/false);

  NEXT_PASS (pass_cleanup_cfg_post_optimizing);

  NEXT_PASS (pass_warn_function_noreturn);



3. Open tree-pass.h file in ~/project/gcc/gcc folder

vi tree-pass.h

You will see the gimple_opt_pass *make_pass_ctyler (gcc::context *ctxt);


4. We then copy all the files to the gcc folder 

5. Lets make sure that tree-ctyler.o is added in the makefile

        tree-assume.o \

        tree-call-cdce.o \

        tree-cfg.o \

        tree-cfgcleanup.o \

        tree-chrec.o \

        tree-complex.o \

        tree-ctyler.o \

        tree-data-ref.o \

        tree-dfa.o \

        tree-diagnostic.o \

        tree-diagnostic-client-data-hooks.o \

        tree-dump.o \

        tree-eh.o \

6. Then we rebuild;

cd gcc1build
time make -j 24 |& tee build.log
make install


I did get alot of errors when tryinf to do this because it kept showing me that there errors in the makefile (*** missing seperators) but when i manage to fix that it would show it for another line and after fixing some of these it would display missing files errors, i went through stackoverflow, and chatgpt for a couple hours to try and figure it out and manage to rebuild but finally it worked.


I will use the same program i used to test the original gcc build before adding these files;
hello.c

#include<stdio.h>

int main() {

        printf("Hello World\n");

        return 0;

}


8. gcc -fdump-tree-all hello.c -o hello to create the dump file which was created as test.c.263t.ctyler:

;; Function main (main, funcdef_no=11, decl_uid=4899, cgraph_uid=12, symbol_order=11) (executed once)
===== Basic block count: 1 =====
----- Statement count: 1 -----
# .MEM_2 = VDEF <.MEM_1(D)>
printf ("Hello World\n");
----- Statement count: 2 -----
# VUSE <.MEM_2>
return 0;
int main ()
{
    <bb 2> [local count: 1073741824]:
    printf ("Hello World\n");
    return 0;
}


9. Now I will modify the tree-ctyler file so it can implement function signature generation to uniquely identify functions and compare signatures to decide prune or no-prune. Below is my implementation for this;


#include "config.h"

#include "system.h"

#include "coretypes.h"

#include "backend.h"

#include "tree.h"

#include "gimple.h"

#include "tree-pass.h"

#include "ssa.h"

#include "gimple-iterator.h"

#include "gimple-walk.h"

#include "tree-pretty-print.h"

#include "diagnostic.h"

#include "dumpfile.h"

#include <string>

#include <functional>

#include <unordered_map>

#include <set>


// Pass metadata

namespace {

const pass_data pass_data_ctyler = {

    GIMPLE_PASS,       /* type */

    "ctyler",          /* name */

    OPTGROUP_NONE,     /* optinfo_flags */

    TV_NONE,           /* tv_id */

    PROP_cfg,          /* properties_required */

    0,                 /* properties_provided */

    0,                 /* properties_destroyed */

    0,                 /* todo_flags_start */

    0                  /* todo_flags_finish */

};


class pass_ctyler : public gimple_opt_pass {

public:

    pass_ctyler(gcc::context *ctxt)

        : gimple_opt_pass(pass_data_ctyler, ctxt) {}


    bool gate(function *) final override {

        return true; 

    }


    unsigned int execute(function *fun) final override;

};


std::string generate_signature(function *fun) {

    std::hash<std::string> hasher;

    size_t hash = 0;


    basic_block bb;

    std::set<std::string> unique_statements;


    FOR_EACH_BB_FN(bb, fun) {

        for (gimple_stmt_iterator gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {

            gimple *stmt = gsi_stmt(gsi);


            std::string stmt_repr = gimple_code_name[gimple_code(stmt)];

            stmt_repr += gimple_get_locus(stmt)->file ? gimple_get_locus(stmt)->file : "unknown";

            stmt_repr += std::to_string(gimple_get_locus(stmt)->line);


            unique_statements.insert(stmt_repr);

        }

    }


    for (const auto &stmt_repr : unique_statements) {

        hash ^= hasher(stmt_repr) + 0x9e3779b9 + (hash << 6) + (hash >> 2);

    }


    return std::to_string(hash);

}


unsigned int pass_ctyler::execute(function *fun) {

    static std::unordered_map<std::string, std::string> function_signatures;


    std::string signature = generate_signature(fun);

    std::string func_name = IDENTIFIER_POINTER(DECL_NAME(fun->decl));


    if (function_signatures.find(signature) != function_signatures.end()) {

        fprintf(dump_file, "PRUNE: %s (Duplicate of %s)\n", func_name.c_str(), function_signatures[signature].c_str());

    } else {

        function_signatures[signature] = func_name;

        fprintf(dump_file, "NOPRUNE: %s\n", func_name.c_str());

    }


    return 0;

}

}


gimple_opt_pass *make_pass_ctyler(gcc::context *ctxt) {

    return new pass_ctyler(ctxt);

}



Now when trying to rebuild I came across the same missing seperator error in the MakeFile, I went through the internet and used AI to help me with this but it didnt help at all. While trying to fix this I also tried removing files from my gcc build folder and rebuild but the error was persistance, even after trying to make manual changes it showed more errors later, so I decided to redo this part on my computer but unfortunately it doesnt have alot of extra storage which made the process really slow and at some point i faced a complete white screen, when trying to use msys2 mingw , I wanted to use the gcc in the spo project folder but it just would set it so i tried with the default one on my computer but after hours of trying it still didnt work. At this point I dont think i have enough time and ways to fix this, in order to try redo it from scratch but I have added all my data in this blog. This has been the hardest project this semester for me (even with 5 courses) and I hope some day I would be able to complete this effortlessly. For now thank you for your time.

Comments

Popular posts from this blog

Building GCC Part 2

Wrapping Up Project : Stage 3