Skip to content

Commit

Permalink
Remove redundant decls
Browse files Browse the repository at this point in the history
Pass through the closure set looking for Decls we can erase. For
example:
```
struct ll;

struct ll;

int get(struct ll *);

struct ll;
```
We just need the first `struct ll;`

Signed-off-by: Giuliano Belinassi <[email protected]>
  • Loading branch information
giulianobelinassi committed Aug 20, 2024
1 parent b68f4e6 commit aeae7a2
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 2 deletions.
24 changes: 22 additions & 2 deletions libcextract/FunctionDepsFinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,10 @@ void FunctionDependencyFinder::Remove_Redundant_Decls(void)
{
ClosureSet &closure = Visitor.Get_Closure();
std::unordered_set<Decl *> &closure_set = closure.Get_Set();
bool inc;

for (auto it = closure_set.begin(); it != closure_set.end(); ++it) {
for (auto it = closure_set.begin(); it != closure_set.end(); inc ? ++it : it) {
inc = true;
/* Handle the case where a enum or struct is declared as:
typedef enum Hand {
Expand Down Expand Up @@ -198,9 +200,27 @@ void FunctionDependencyFinder::Remove_Redundant_Decls(void)
}
}
}

/* Try to remove any decls in the main file which are
redundant, which means that have equivalent previous decl. */
Decl *decl = *it;

if (AST->isInMainFileID(decl->getBeginLoc()) &&
AST->isInMainFileID(decl->getEndLoc())) {

for (Decl *prev = decl->getPreviousDecl();
prev != nullptr;
prev = prev->getPreviousDecl()) {
if (closure.Is_Decl_Marked(prev) && Is_Decl_Equivalent_To(decl, prev)) {
++it;
inc = false;
closure.Remove_Decl(decl);
break;
}
}
}
}

// FIXME: use interval tree
ASTUnit::top_level_iterator it;
Decl *prev = nullptr;
for (it = AST->top_level_begin(); it != AST->top_level_end(); ++it) {
Expand Down
19 changes: 19 additions & 0 deletions libcextract/LLVMMisc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,3 +281,22 @@ DeclContextLookupResult Get_Decl_From_Symtab(ASTUnit *ast, const StringRef &name

return Get_Decl_From_Symtab(ast, info->getValue());
}

/** Check if two Decls are equivalent. */
bool Is_Decl_Equivalent_To(Decl *a, Decl *b)
{
std::string a_str;
std::string b_str;

llvm::raw_string_ostream a_stream(a_str);
llvm::raw_string_ostream b_stream(b_str);

a->print(a_stream);
b->print(b_stream);

if (a_str == b_str) {
return true;
}

return false;
}
3 changes: 3 additions & 0 deletions libcextract/LLVMMisc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,6 @@ DeclContextLookupResult Get_Decl_From_Symtab(ASTUnit *ast, const IdentifierInfo

/** Lookup in the symbol table for a declaration with given name passed by name. */
DeclContextLookupResult Get_Decl_From_Symtab(ASTUnit *ast, const StringRef &name);

/** Check if two Decls are equivalent. */
bool Is_Decl_Equivalent_To(Decl *a, Decl *b);
16 changes: 16 additions & 0 deletions testsuite/small/redundant-1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_NO_EXTERNALIZATION" }*/

struct ll;

struct ll;

int get(struct ll *);

struct ll;

int f(struct ll *l)
{
return get(l);
}

/* { dg-final { scan-tree-dump-not "struct ll;\n+int get\(struct ll \*\);" } } */

0 comments on commit aeae7a2

Please sign in to comment.