mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-12 04:43:48 +00:00
[Refactor][NfC] Simplify and clean the handling of (new) access relations
This patch does not change the semantic on it's own. However, the dependence analysis as well as dce will now use the newest available access relation for each memory access, thus if at some point the json importer or any other pass will run before those two and set a new access relation the behaviour will be different. In general it is unclear if the dependence analysis and dce should be run on the old or new access functions anyway. If we need to access the original access function from the outside later, we can expose the getter again. Differential Revision: http://reviews.llvm.org/D5707 llvm-svn: 219612
This commit is contained in:
parent
f305000a91
commit
a99130f042
@ -208,6 +208,15 @@ private:
|
||||
|
||||
void assumeNoOutOfBound(const IRAccess &Access);
|
||||
|
||||
/// @brief Get the original access function as read from IR.
|
||||
isl_map *getOriginalAccessRelation() const;
|
||||
|
||||
/// @brief Return the space in which the access relation lives in.
|
||||
__isl_give isl_space *getOriginalAccessRelationSpace() const;
|
||||
|
||||
/// @brief Get the new access function imported or set by a pass
|
||||
isl_map *getNewAccessRelation() const;
|
||||
|
||||
public:
|
||||
/// @brief Create a memory access from an access in LLVM-IR.
|
||||
///
|
||||
@ -238,13 +247,30 @@ public:
|
||||
/// @brief Is this a write memory access?
|
||||
bool isWrite() const { return isMustWrite() || isMayWrite(); }
|
||||
|
||||
isl_map *getAccessRelation() const;
|
||||
/// @brief Check if a new access relation was imported or set by a pass.
|
||||
bool hasNewAccessRelation() const { return newAccessRelation; }
|
||||
|
||||
/// @brief Return the space in which the access relation lives in.
|
||||
__isl_give isl_space *getAccessRelationSpace() const;
|
||||
/// @brief Return the newest access relation of this access.
|
||||
///
|
||||
/// There are two possibilities:
|
||||
/// 1) The original access relation read from the LLVM-IR.
|
||||
/// 2) A new access relation imported from a json file or set by another
|
||||
/// pass (e.g., for privatization).
|
||||
///
|
||||
/// As 2) is by construction "newer" than 1) we return the new access
|
||||
/// relation if present.
|
||||
///
|
||||
isl_map *getAccessRelation() const {
|
||||
return hasNewAccessRelation() ? getNewAccessRelation()
|
||||
: getOriginalAccessRelation();
|
||||
}
|
||||
|
||||
/// @brief Get an isl string representing this access function.
|
||||
std::string getAccessRelationStr() const;
|
||||
/// @brief Return the access relation after the schedule was applied.
|
||||
__isl_give isl_pw_multi_aff *
|
||||
applyScheduleToAccessRelation(__isl_keep isl_union_map *Schedule) const;
|
||||
|
||||
/// @brief Get an isl string representing the access function read from IR.
|
||||
std::string getOriginalAccessRelationStr() const;
|
||||
|
||||
/// @brief Get the base address of this access (e.g. A for A[i+j]).
|
||||
Value *getBaseAddr() const { return BaseAddr; }
|
||||
@ -266,9 +292,6 @@ public:
|
||||
/// @brief Return the access instruction of this memory access.
|
||||
Instruction *getAccessInstruction() const { return Inst; }
|
||||
|
||||
/// @brief Get the new access function imported from JSCOP file
|
||||
isl_map *getNewAccessRelation() const;
|
||||
|
||||
/// Get the stride of this memory access in the specified Schedule. Schedule
|
||||
/// is a map from the statement to a schedule where the innermost dimension is
|
||||
/// the dimension of the innermost loop containing the statement.
|
||||
|
@ -397,15 +397,27 @@ isl_id *MemoryAccess::getArrayId() const {
|
||||
return isl_map_get_tuple_id(AccessRelation, isl_dim_out);
|
||||
}
|
||||
|
||||
isl_map *MemoryAccess::getAccessRelation() const {
|
||||
isl_pw_multi_aff *
|
||||
MemoryAccess::applyScheduleToAccessRelation(isl_union_map *USchedule) const {
|
||||
isl_map *Schedule, *ScheduledAccRel;
|
||||
isl_union_set *UDomain;
|
||||
|
||||
UDomain = isl_union_set_from_set(getStatement()->getDomain());
|
||||
USchedule = isl_union_map_intersect_domain(USchedule, UDomain);
|
||||
Schedule = isl_map_from_union_map(USchedule);
|
||||
ScheduledAccRel = isl_map_apply_domain(getAccessRelation(), Schedule);
|
||||
return isl_pw_multi_aff_from_map(ScheduledAccRel);
|
||||
}
|
||||
|
||||
isl_map *MemoryAccess::getOriginalAccessRelation() const {
|
||||
return isl_map_copy(AccessRelation);
|
||||
}
|
||||
|
||||
std::string MemoryAccess::getAccessRelationStr() const {
|
||||
std::string MemoryAccess::getOriginalAccessRelationStr() const {
|
||||
return stringFromIslObj(AccessRelation);
|
||||
}
|
||||
|
||||
__isl_give isl_space *MemoryAccess::getAccessRelationSpace() const {
|
||||
__isl_give isl_space *MemoryAccess::getOriginalAccessRelationSpace() const {
|
||||
return isl_map_get_space(AccessRelation);
|
||||
}
|
||||
|
||||
@ -444,7 +456,7 @@ isl_basic_map *MemoryAccess::createBasicAccessMap(ScopStmt *Statement) {
|
||||
// constraints is the set of constraints that needs to be assumed to ensure such
|
||||
// statement instances are never executed.
|
||||
void MemoryAccess::assumeNoOutOfBound(const IRAccess &Access) {
|
||||
isl_space *Space = isl_space_range(getAccessRelationSpace());
|
||||
isl_space *Space = isl_space_range(getOriginalAccessRelationSpace());
|
||||
isl_set *Outside = isl_set_empty(isl_space_copy(Space));
|
||||
for (int i = 1, Size = Access.Subscripts.size(); i < Size; ++i) {
|
||||
isl_local_space *LS = isl_local_space_from_space(isl_space_copy(Space));
|
||||
@ -565,7 +577,7 @@ void MemoryAccess::print(raw_ostream &OS) const {
|
||||
break;
|
||||
}
|
||||
OS << "[Reduction Type: " << getReductionType() << "]\n";
|
||||
OS.indent(16) << getAccessRelationStr() << ";\n";
|
||||
OS.indent(16) << getOriginalAccessRelationStr() << ";\n";
|
||||
}
|
||||
|
||||
void MemoryAccess::dump() const { print(errs()); }
|
||||
@ -618,9 +630,7 @@ static isl_map *getEqualAndLarger(isl_space *setDomain) {
|
||||
|
||||
isl_set *MemoryAccess::getStride(__isl_take const isl_map *Schedule) const {
|
||||
isl_map *S = const_cast<isl_map *>(Schedule);
|
||||
isl_map *AccessRelation = getNewAccessRelation();
|
||||
if (!AccessRelation)
|
||||
AccessRelation = getAccessRelation();
|
||||
isl_map *AccessRelation = getAccessRelation();
|
||||
isl_space *Space = isl_space_range(isl_map_get_space(S));
|
||||
isl_map *NextScatt = getEqualAndLarger(Space);
|
||||
|
||||
|
@ -165,25 +165,15 @@ void BlockGenerator::copyInstScalar(const Instruction *Inst, ValueMapT &BBMap,
|
||||
}
|
||||
|
||||
Value *BlockGenerator::getNewAccessOperand(const MemoryAccess &MA) {
|
||||
isl_pw_multi_aff *PWSchedule, *PWAccRel;
|
||||
isl_union_map *ScheduleU;
|
||||
isl_map *Schedule, *AccRel;
|
||||
isl_pw_multi_aff *PWAccRel;
|
||||
isl_union_map *Schedule;
|
||||
isl_ast_expr *Expr;
|
||||
|
||||
assert(ExprBuilder && Build &&
|
||||
"Cannot generate new value without IslExprBuilder!");
|
||||
|
||||
AccRel = MA.getNewAccessRelation();
|
||||
assert(AccRel && "We generate new code only for new access relations!");
|
||||
|
||||
ScheduleU = isl_ast_build_get_schedule(Build);
|
||||
ScheduleU = isl_union_map_intersect_domain(
|
||||
ScheduleU, isl_union_set_from_set(MA.getStatement()->getDomain()));
|
||||
Schedule = isl_map_from_union_map(ScheduleU);
|
||||
|
||||
PWSchedule = isl_pw_multi_aff_from_map(isl_map_reverse(Schedule));
|
||||
PWAccRel = isl_pw_multi_aff_from_map(AccRel);
|
||||
PWAccRel = isl_pw_multi_aff_pullback_pw_multi_aff(PWAccRel, PWSchedule);
|
||||
Schedule = isl_ast_build_get_schedule(Build);
|
||||
PWAccRel = MA.applyScheduleToAccessRelation(Schedule);
|
||||
|
||||
Expr = isl_ast_build_access_from_pw_multi_aff(Build, PWAccRel);
|
||||
Expr = isl_ast_expr_address_of(Expr);
|
||||
@ -197,16 +187,14 @@ Value *BlockGenerator::generateLocationAccessed(const Instruction *Inst,
|
||||
ValueMapT &GlobalMap,
|
||||
LoopToScevMapT <S) {
|
||||
const MemoryAccess &MA = Statement.getAccessFor(Inst);
|
||||
isl_map *NewAccRel = MA.getNewAccessRelation();
|
||||
|
||||
Value *NewPointer;
|
||||
if (NewAccRel)
|
||||
if (MA.hasNewAccessRelation())
|
||||
NewPointer = getNewAccessOperand(MA);
|
||||
else
|
||||
NewPointer =
|
||||
getNewValue(Pointer, BBMap, GlobalMap, LTS, getLoopForInst(Inst));
|
||||
|
||||
isl_map_free(NewAccRel);
|
||||
return NewPointer;
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ Json::Value JSONExporter::getJSON(Scop &scop) const {
|
||||
Json::Value access;
|
||||
|
||||
access["kind"] = MA->isRead() ? "read" : "write";
|
||||
access["relation"] = MA->getAccessRelationStr();
|
||||
access["relation"] = MA->getOriginalAccessRelationStr();
|
||||
|
||||
statement["accesses"].append(access);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user