Skip to content

Commit

Permalink
Adding bounds inference of the form count(i+1) (#602)
Browse files Browse the repository at this point in the history
* Adding bounds inferrence of the form count(i+1)

* Fixing Review comments

* Fixing issue where the declaration has only types
  • Loading branch information
Machiry authored Jun 18, 2021
1 parent b75d0a3 commit 2a96dfb
Show file tree
Hide file tree
Showing 19 changed files with 295 additions and 155 deletions.
20 changes: 18 additions & 2 deletions clang/include/clang/3C/ABounds.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,16 @@ class ABounds {
InvalidKind,
// Bounds that represent number of items.
CountBoundKind,
// Count bounds but plus one, i.e., count(i+1)
CountPlusOneBoundKind,
// Bounds that represent number of bytes.
ByteBoundKind,
// Bounds that represent range.
RangeBoundKind,
};
BoundsKind getKind() const { return Kind; }

private:
protected:
BoundsKind Kind;

protected:
Expand Down Expand Up @@ -83,10 +85,24 @@ class CountBound : public ABounds {

BoundsKey getCountVar() { return CountVar; }

private:
protected:
BoundsKey CountVar;
};

class CountPlusOneBound : public CountBound {
public:
CountPlusOneBound(BoundsKey Var) : CountBound(Var) {
this->Kind = CountPlusOneBoundKind;
}

std::string mkString(AVarBoundsInfo *ABI, clang::Decl *D = nullptr) override;
bool areSame(ABounds *O, AVarBoundsInfo *ABI) override;

static bool classof(const ABounds *S) {
return S->getKind() == CountPlusOneBoundKind;
}
};

class ByteBound : public ABounds {
public:
ByteBound(BoundsKey Var) : ABounds(ByteBoundKind), ByteVar(Var) {
Expand Down
40 changes: 35 additions & 5 deletions clang/include/clang/3C/AVarBoundsInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ class AvarBoundsInference {
bool hasImpossibleBounds(BoundsKey BK);
// Set the given pointer to have impossible bounds.
void setImpossibleBounds(BoundsKey BK);
// Infer bounds of the given pointer key from potential bounds.
bool inferFromPotentialBounds(BoundsKey BK, AVarGraph &BKGraph);

AVarBoundsInfo *BI;

Expand All @@ -147,6 +149,31 @@ class AvarBoundsInference {
std::set<BoundsKey> BKsFailedFlowInference;
};

// Class that maintains information about potential bounds for
// various pointer variables.
class PotentialBoundsInfo {
public:
PotentialBoundsInfo() {
PotentialCntBounds.clear();
PotentialCntPOneBounds.clear();
}
// Count Bounds, i.e., count(i).
bool hasPotentialCountBounds(BoundsKey PtrBK);
std::set<BoundsKey> &getPotentialBounds(BoundsKey PtrBK);
void addPotentialBounds(BoundsKey BK, const std::set<BoundsKey> &PotK);

// Count Bounds Plus one, i.e., count(i+1).
bool hasPotentialCountPOneBounds(BoundsKey PtrBK);
std::set<BoundsKey> &getPotentialBoundsPOne(BoundsKey PtrBK);
void addPotentialBoundsPOne(BoundsKey BK, const std::set<BoundsKey> &PotK);
private:
// This is the map of pointer variable bounds key and set of bounds key
// which can be the count bounds.
std::map<BoundsKey, std::set<BoundsKey>> PotentialCntBounds;
// Potential count + 1 bounds.
std::map<BoundsKey, std::set<BoundsKey>> PotentialCntPOneBounds;
};

class AVarBoundsInfo {
public:
AVarBoundsInfo() : ProgVarGraph(this), CtxSensProgVarGraph(this),
Expand All @@ -171,7 +198,10 @@ class AVarBoundsInfo {
bool replaceBounds(BoundsKey L, BoundsPriority P, ABounds *B);
ABounds *getBounds(BoundsKey L, BoundsPriority ReqP = Invalid,
BoundsPriority *RetP = nullptr);
bool updatePotentialCountBounds(BoundsKey BK, std::set<BoundsKey> &CntBK);
void updatePotentialCountBounds(BoundsKey BK,
const std::set<BoundsKey> &CntBK);
void updatePotentialCountPOneBounds(BoundsKey BK,
const std::set<BoundsKey> &CntBK);

// Try and get BoundsKey, into R, for the given declaration. If the
// declaration does not have a BoundsKey then return false.
Expand Down Expand Up @@ -316,9 +346,8 @@ class AVarBoundsInfo {
AVarGraph RevCtxSensProgVarGraph;
// Stats on techniques used to find length for various variables.
AVarBoundsStats BoundsInferStats;
// This is the map of pointer variable bounds key and set of bounds key
// which can be the count bounds.
std::map<BoundsKey, std::set<BoundsKey>> PotentialCntBounds;
// Information about potential bounds.
PotentialBoundsInfo PotBoundsInfo;
// Context-sensitive bounds key handler
CtxSensitiveBoundsKeyHandler CSBKeyHandler;

Expand Down Expand Up @@ -351,7 +380,8 @@ class AVarBoundsInfo {
// Perform worklist based inference on the requested array variables using
// the provided graph and potential length variables.
bool performWorkListInference(const std::set<BoundsKey> &ArrNeededBounds,
AVarGraph &BKGraph, AvarBoundsInference &BI);
AVarGraph &BKGraph, AvarBoundsInference &BI,
bool FromPB);

void insertParamKey(ParamDeclType ParamDecl, BoundsKey NK);
};
Expand Down
31 changes: 20 additions & 11 deletions clang/lib/3C/ABounds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ std::string ABounds::getBoundsKeyStr(BoundsKey BK,
if (FD->getNumParams() > PIdx) {
auto *NewPVD = FD->getParamDecl(PIdx);
BKStr = NewPVD->getNameAsString();
// If the parameter in the new declaration does not have a name?
// then use the old name.
if (BKStr.empty())
BKStr = PV->mkString();
}
}
return BKStr;
Expand All @@ -93,16 +97,24 @@ BoundsKey CountBound::getBKey() { return this->CountVar; }

ABounds *CountBound::makeCopy(BoundsKey NK) { return new CountBound(NK); }

std::string CountPlusOneBound::mkString(AVarBoundsInfo *ABI, clang::Decl *D) {
std::string CVar = ABounds::getBoundsKeyStr(CountVar, ABI, D);
return "count(" + CVar + " + 1)";
}

bool CountPlusOneBound::areSame(ABounds *O, AVarBoundsInfo *ABI) {
if (CountPlusOneBound *OT = dyn_cast_or_null<CountPlusOneBound>(O))
return ABI->areSameProgramVar(this->CountVar, OT->CountVar);
return false;
}

std::string ByteBound::mkString(AVarBoundsInfo *ABI, clang::Decl *D) {
return "byte_count(" + ABounds::getBoundsKeyStr(ByteVar, ABI, D) + ")";
}

bool ByteBound::areSame(ABounds *O, AVarBoundsInfo *ABI) {
if (O != nullptr) {
if (ByteBound *BB = dyn_cast<ByteBound>(O)) {
return ABI->areSameProgramVar(this->ByteVar, BB->ByteVar);
}
}
if (ByteBound *BB = dyn_cast_or_null<ByteBound>(O))
return ABI->areSameProgramVar(this->ByteVar, BB->ByteVar);
return false;
}

Expand All @@ -118,11 +130,8 @@ std::string RangeBound::mkString(AVarBoundsInfo *ABI, clang::Decl *D) {
}

bool RangeBound::areSame(ABounds *O, AVarBoundsInfo *ABI) {
if (O != nullptr) {
if (RangeBound *RB = dyn_cast<RangeBound>(O)) {
return ABI->areSameProgramVar(this->LB, RB->LB) &&
ABI->areSameProgramVar(this->UB, RB->UB);
}
}
if (RangeBound *RB = dyn_cast_or_null<RangeBound>(O))
return ABI->areSameProgramVar(this->LB, RB->LB) &&
ABI->areSameProgramVar(this->UB, RB->UB);
return false;
}
Loading

0 comments on commit 2a96dfb

Please sign in to comment.