Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BoundsWidening] Use invertibility to support bounds widening in loops #1137

Merged
merged 3 commits into from
Jul 27, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 49 additions & 10 deletions clang/include/clang/Sema/BoundsWideningAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "clang/AST/ExprUtils.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/Analysis/Analyses/PostOrderCFGView.h"
#include "clang/Sema/BoundsUtils.h"
#include "clang/Sema/CheckedCAnalysesPrepass.h"
#include "clang/Sema/Sema.h"

Expand Down Expand Up @@ -54,6 +55,14 @@ namespace clang {
// for printing the blocks in a deterministic order.
using OrderedBlocksTy = std::vector<const CFGBlock *>;

// A tuple (Tup) of three elements such that we need to replace Tup[0] with
// Tup[1] in the bounds of every pointer in Tup[3].
using LValuesToReplaceInBoundsTy = std::tuple<Expr *, Expr *, VarSetTy>;

// A mapping of invertible statements to LValuesToReplaceInBoundsTy.
using InvertibleStmtMapTy = llvm::DenseMap<const Stmt *,
LValuesToReplaceInBoundsTy>;

} // end namespace clang

namespace clang {
Expand Down Expand Up @@ -128,20 +137,20 @@ namespace clang {
// Get the set of variables that are pointers to null-terminated arrays and
// in whose lower bounds expressions the variables in Vars occur.
// @param[in] Vars is a set of variables.
// @param[out] NullTermPtrsWithVarsInLowerBounds is a set of variables that
// are pointers to null-terminated arrays and in whose lower bounds
// expressions the variables in Vars occur.
void GetNullTermPtrsWithVarsInLowerBounds(
VarSetTy &Vars, VarSetTy &NullTermPtrsWithVarsInLowerBounds) const;
// @param[out] PtrsWithVarsInLowerBounds is a set of variables that are
// pointers to null-terminated arrays and in whose lower bounds expressions
// the variables in Vars occur.
void GetPtrsWithVarsInLowerBounds(
VarSetTy &Vars, VarSetTy &PtrsWithVarsInLowerBounds) const;

// Get the set of variables that are pointers to null-terminated arrays and
// in whose upper bounds expressions the variables in Vars occur.
// @param[in] Vars is a set of variables.
// @param[out] NullTermPtrsWithVarsInLowerBounds is a set of variables that
// are pointers to null-terminated arrays and in whose upper bounds
// expressions the variables in Vars occur.
void GetNullTermPtrsWithVarsInUpperBounds(
VarSetTy &Vars, VarSetTy &NullTermPtrsWithVarsInUpperBounds) const;
// @param[out] PtrsWithVarsInLowerBounds is a set of variables that are
// pointers to null-terminated arrays and in whose upper bounds expressions
// the variables in Vars occur.
void GetPtrsWithVarsInUpperBounds(
VarSetTy &Vars, VarSetTy &PtrsWithVarsInUpperBounds) const;

// Add an offset to a given expression.
// @param[in] E is the given expression.
Expand Down Expand Up @@ -287,6 +296,14 @@ namespace clang {
// The Out set of the previous statement of a statement in a block.
BoundsMapTy OutOfPrevStmt;

// This stores the adjusted bounds after we have determined the
// invertibility of the current statement that modifies variables
// occurring in bounds expressions.
StmtBoundsMapTy AdjustedBounds;

// A mapping of invertible statements to LValuesToReplaceInBoundsTy.
InvertibleStmtMapTy InvertibleStmts;

ElevatedCFGBlock(const CFGBlock *B) : Block(B) {}

}; // end of ElevatedCFGBlock class.
Expand Down Expand Up @@ -492,6 +509,28 @@ namespace clang {
const Stmt *CurrStmt,
BoundsMapTy &VarsAndBounds);

// Check if CurrStmt is invertible w.r.t. the variables modified by
// CurrStmt.
// Note: This function modifies the set EB->InvertibleStmts.
// @param[in] EB is the current ElevatedCFGBlock.
// @param[in] CurrStmt is the current statement.
// @param[in] PtrsWithAffectedBounds is the set of variables that are
// pointers to null-terminated arrays whose bounds are affected by
// modification to variables that occur in their bounds expressions by
// CurrStmt.
void CheckStmtInvertibility(ElevatedCFGBlock *EB,
const Stmt *CurrStmt,
VarSetTy PtrsWithAffectedBounds) const;

// Update the bounds in StmtOut with the adjusted bounds for the current
// statement, if they exist.
// @param[in] EB is the current ElevatedCFGBlock.
// @param[in] CurrStmt is the current statement.
// @param[out] StmtOut is updated with the adjusted bounds for CurrStmt, if
// they exist.
void UpdateAdjustedBounds(ElevatedCFGBlock *EB, const Stmt *CurrStmt,
BoundsMapTy &StmtOut) const;

// Order the blocks by block number to get a deterministic iteration order
// for the blocks.
// @return Blocks ordered by block number from higher to lower since block
Expand Down
Loading