From 5bbcf6a723a45989e0a189a30e663a4d38b5f006 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Tue, 2 Dec 2014 01:44:49 +0100 Subject: mds-kbdc: dead code elimination MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/mds-kbdc/eliminate-dead-code.c | 52 +++++++++++++++++++++++++------------- src/mds-kbdc/tree.h | 44 ++++++++++++++++++++------------ 2 files changed, 62 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/mds-kbdc/eliminate-dead-code.c b/src/mds-kbdc/eliminate-dead-code.c index 5f16bc3..cedf576 100644 --- a/src/mds-kbdc/eliminate-dead-code.c +++ b/src/mds-kbdc/eliminate-dead-code.c @@ -101,6 +101,13 @@ static size_t includes_size = 0; */ static size_t includes_ptr = 0; +/** + * 2: Eliminating because of a return-statement + * 1: Eliminating because of a break- or continue-statement + * 0: Not eliminating + */ +static int elimination_level = 0; + /** @@ -164,18 +171,6 @@ static int eliminate_include(mds_kbdc_tree_include_t* restrict tree) } -/** - * Eliminate dead code in a for-loop - * - * @param tree The tree to reduce - * @return Zero on success, -1 on error - */ -static int eliminate_for(mds_kbdc_tree_for_t* restrict tree) -{ - return eliminate_subtree(tree->inner); -} - - /** * Eliminate dead code in an if-statement * @@ -184,8 +179,15 @@ static int eliminate_for(mds_kbdc_tree_for_t* restrict tree) */ static int eliminate_if(mds_kbdc_tree_if_t* restrict tree) { - return -(eliminate_subtree(tree->inner) || - eliminate_subtree(tree->otherwise)); + int elimination; + fail_if (eliminate_subtree(tree->inner)); + elimination = elimination_level, elimination_level = 0; + fail_if (eliminate_subtree(tree->otherwise)); + if (elimination > elimination_level) + elimination = elimination_level; + return 0; + pfail: + return -1; } @@ -206,22 +208,37 @@ static int eliminate_subtree(mds_kbdc_tree_t* restrict tree) switch (tree->type) { + case C(INCLUDE): e(include); break; + case C(IF): E(if); break; case C(INFORMATION): case C(FUNCTION): case C(MACRO): case C(ASSUMPTION): + case C(FOR): if ((r = eliminate_subtree(tree->information.inner))) return r; + if ((tree->type == C(FUNCTION)) || (tree->type == C(MACRO))) elimination_level = 0; + else if ((tree->type == C(FOR)) && (elimination_level == 1)) elimination_level = 0; + break; + case C(RETURN): + case C(BREAK): + case C(CONTINUE): + elimination_level = tree->type == C(RETURN) ? 2 : 1; break; - case C(INCLUDE): e(include); break; - case C(FOR): E(for); break; - case C(IF): E(if); break; default: break; } + if (tree->next && elimination_level) + { + NEW_ERROR(tree->next, includes_ptr, WARNING, "statement is unreachable"); + mds_kbdc_tree_free(tree->next), tree->next = NULL; + } + tree = tree->next; goto again; + pfail: + return -1; #undef E #undef e } @@ -255,4 +272,3 @@ int eliminate_dead_code(mds_kbdc_parsed_t* restrict result_) #undef NEW_ERROR_WITHOUT_INCLUDES #undef C - diff --git a/src/mds-kbdc/tree.h b/src/mds-kbdc/tree.h index fe67faf..2d9a278 100644 --- a/src/mds-kbdc/tree.h +++ b/src/mds-kbdc/tree.h @@ -283,14 +283,14 @@ typedef struct mds_kbdc_tree_include MDS_KBDC_TREE_COMMON; /** - * The filename of the file to include + * The included layout code tree */ - char* filename; + mds_kbdc_tree_t* inner; /** - * The included layout code tree + * The filename of the file to include */ - mds_kbdc_tree_t* inner; + char* filename; /** * The source code of the file included by this statement @@ -312,17 +312,23 @@ struct mds_kbdc_tree_callable { MDS_KBDC_TREE_COMMON; - /** - * The name of the callable - */ - char* name; - /** * The first child node, `.inner.next` * is used to access the second child node */ mds_kbdc_tree_t* inner; + /* It is important that `.inner` is first because + * it is first in `struct mds_kbdc_tree_nesting` + * too which means that `.inner` has to same + * offset everyever (except in `mds_kbdc_tree_if_t`). + */ + + /** + * The name of the callable + */ + char* name; + MDS_KBDC_TREE_PADDING(2); }; @@ -410,6 +416,19 @@ typedef struct mds_kbdc_tree_for { MDS_KBDC_TREE_COMMON; + /** + * The first child node, `.inner.next` is + * used to access the second child node. + * This is what should be done inside the loop. + */ + mds_kbdc_tree_t* inner; + + /* It is important that `.inner` is first because + * it is first in `struct mds_kbdc_tree_nesting` + * too which means that `.inner` has to same + * offset everyever (except in `mds_kbdc_tree_if_t`). + */ + /** * The first value to variable should take, inclusive */ @@ -425,13 +444,6 @@ typedef struct mds_kbdc_tree_for */ char* variable; - /** - * The first child node, `.inner.next` is - * used to access the second child node. - * This is what should be done inside the loop. - */ - mds_kbdc_tree_t* inner; - MDS_KBDC_TREE_PADDING(4); } mds_kbdc_tree_for_t; -- cgit v1.2.3-70-g09d2