aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-04-15 13:37:50 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-07-01 00:18:44 +0200
commit8cb5317fa01679fd8b2b30ffbf8dec13ae71c98d (patch)
treea27db0ecaec527b69c4d8e7e1e5a450eb945d4bb
parentea44f850aa68db74283986b47f617d38d2f63fed (diff)
downloadsparse-dev-8cb5317fa01679fd8b2b30ffbf8dec13ae71c98d.tar.gz
add PSEUDO_UNDEF & undef_pseudo()
Processing in the middle-end are much easier if undefined values have been clearly identified. Once done, we can then make choices like: - give some warnings about uninitialized variables - always initialize them to zero - allow arbitraly simplification - ... Prepare this by declaring a new type of pseudo: PSEUDO_UNDEF somewhat similar to PSEUDO_VOID. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--linearize.c9
-rw-r--r--linearize.h4
-rw-r--r--sparse-llvm.c6
3 files changed, 18 insertions, 1 deletions
diff --git a/linearize.c b/linearize.c
index 194afe66..7aecc9af 100644
--- a/linearize.c
+++ b/linearize.c
@@ -172,6 +172,8 @@ const char *show_pseudo(pseudo_t pseudo)
if (pseudo->ident)
sprintf(buf+i, "(%s)", show_ident(pseudo->ident));
break;
+ case PSEUDO_UNDEF:
+ return "UNDEF";
default:
snprintf(buf, 64, "<bad pseudo type %d>", pseudo->type);
}
@@ -830,6 +832,13 @@ pseudo_t value_pseudo(long long val)
return pseudo;
}
+pseudo_t undef_pseudo(void)
+{
+ pseudo_t pseudo = __alloc_pseudo(0);
+ pseudo->type = PSEUDO_UNDEF;
+ return pseudo;
+}
+
static pseudo_t argument_pseudo(struct entrypoint *ep, int nr)
{
pseudo_t pseudo = __alloc_pseudo(0);
diff --git a/linearize.h b/linearize.h
index 5e776693..c30c826d 100644
--- a/linearize.h
+++ b/linearize.h
@@ -21,6 +21,7 @@ DECLARE_PTR_LIST(pseudo_user_list, struct pseudo_user);
enum pseudo_type {
PSEUDO_VOID,
+ PSEUDO_UNDEF,
PSEUDO_REG,
PSEUDO_SYM,
PSEUDO_VAL,
@@ -331,7 +332,7 @@ static inline void add_pseudo_user_ptr(struct pseudo_user *user, struct pseudo_u
static inline int has_use_list(pseudo_t p)
{
- return (p && p->type != PSEUDO_VOID && p->type != PSEUDO_VAL);
+ return (p && p->type != PSEUDO_VOID && p->type != PSEUDO_UNDEF && p->type != PSEUDO_VAL);
}
static inline int pseudo_user_list_size(struct pseudo_user_list *list)
@@ -388,6 +389,7 @@ struct instruction *alloc_phisrc(pseudo_t pseudo, struct symbol *type);
pseudo_t alloc_phi(struct basic_block *source, pseudo_t pseudo, struct symbol *type);
pseudo_t alloc_pseudo(struct instruction *def);
pseudo_t value_pseudo(long long val);
+pseudo_t undef_pseudo(void);
struct entrypoint *linearize_symbol(struct symbol *sym);
int unssa(struct entrypoint *ep);
diff --git a/sparse-llvm.c b/sparse-llvm.c
index d28eb6e7..cce2baa5 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -270,6 +270,9 @@ static const char *pseudo_name(pseudo_t pseudo, char *buf)
case PSEUDO_VOID:
buf[0] = '\0';
break;
+ case PSEUDO_UNDEF:
+ assert(0);
+ break;
default:
assert(0);
}
@@ -387,6 +390,9 @@ static LLVMValueRef pseudo_to_value(struct function *fn, struct symbol *ctype, p
case PSEUDO_VOID:
result = NULL;
break;
+ case PSEUDO_UNDEF:
+ result = LLVMGetUndef(symbol_type(ctype));
+ break;
default:
assert(0);
}