CGRAOmp  0.1
VerifyPass.hpp
Go to the documentation of this file.
1 /*
2 * MIT License
3 *
4 * Copyright (c) 2021 Amano laboratory, Keio University & Processor Research Team, RIKEN Center for Computational Science
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy of
7 * this software and associated documentation files (the "Software"), to deal in
8 * the Software without restriction, including without limitation the rights to
9 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10 * of the Software, and to permit persons to whom the Software is furnished to do
11 * so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 *
24 * File: /include/VerifyPass.hpp
25 * Project: CGRAOmp
26 * Author: Takuya Kojima in The University of Tokyo (tkojima@hal.ipc.i.u-tokyo.ac.jp)
27 * Created Date: 27-08-2021 15:00:17
28 * Last Modified: 17-07-2022 19:36:44
29 */
30 #ifndef VerifyPass_H
31 #define VerifyPass_H
32 
33 #include "llvm/ADT/DenseMap.h"
34 #include "llvm/ADT/DenseSet.h"
35 #include "llvm/ADT/iterator_range.h"
36 #include "llvm/Analysis/LoopAnalysisManager.h"
37 #include "llvm/Analysis/LoopInfo.h"
38 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
39 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
40 #include "llvm/IR/DiagnosticInfo.h"
41 #include "llvm/IR/Function.h"
42 #include "llvm/IR/PassManager.h"
43 #include "llvm/Passes/PassBuilder.h"
44 #include "llvm/Passes/PassPlugin.h"
45 #include "llvm/Support/Debug.h"
46 #include "llvm/Support/raw_ostream.h"
47 
48 #include "CGRAOmpPass.hpp"
49 #include "DecoupledAnalysis.hpp"
50 #include "CGRAModel.hpp"
51 
52 
53 #include <map>
54 
55 using namespace llvm;
56 
57 
58 namespace CGRAOmp {
59  // Verification Kind
64  enum class VerificationKind {
70  Decoupling,
83  // Inside loop
88  };
89 
90  class VerifyPass;
91 
97  public:
101  explicit VerifyResultBase(VerificationKind kind) : kind(kind) {};
102 
104  VerifyResultBase() = delete;
105 
113  explicit operator bool() {
114  return this->bool_operator_impl();
115  }
116 
117 
118  // interface to print messages
124  virtual void print(raw_ostream &OS) const = 0;
128  void dump() { this->print(dbgs()); }
132  friend raw_ostream& operator<<(raw_ostream& OS,
133  const VerifyResultBase &v) {
134  v.print(OS);
135  return OS;
136  }
137 
138  virtual StringRef getName() const = 0;
139 
143  void setVio() { isViolate = true; }
144 
149  virtual VerificationKind getKind() const {
150  return kind;
151  }
152 
153  protected:
157  virtual bool bool_operator_impl() {
158  return !isViolate;
159  }
160  bool isViolate = false;
161 
162 
163  private:
165  };
166 
167 
173 
174  public:
175  using result_iterator = DenseMap<int, VerifyResultBase*>::iterator;
176 
181  void print(raw_ostream &OS) const override;
182 
183  static bool classof(const VerifyResultBase* R) {
184  return R->getKind() == VerificationKind::KernelSummary;
185  }
186 
192  each_result[static_cast<int>(R->getKind())] = R;
193  }
194 
195  BranchInst* getBackBranch(Loop* L) {
196  if (back_branch_list.find(L) != back_branch_list.end()) {
197  return back_branch_list[L];
198  } else {
199  return nullptr;
200  }
201  }
202 
203  CmpInst* getBackCondition(Loop *L) {
204  if (auto back = getBackBranch(L)) {
205  return dyn_cast<CmpInst>(back->getCondition());
206  } else {
207  return nullptr;
208  }
209  }
210 
211  void setBackBranch(Loop*L, BranchInst* B) {
212  back_branch_list[L] = B;
213  }
214 
216  return each_result.begin();
217  }
218 
220  return each_result.end();
221  }
222 
223  iterator_range<result_iterator> results() {
224  return make_range(result_begin(), result_end());
225  }
226 
227  StringRef getName() const {
228  return "Loop verify result summary";
229  }
230 
232  auto result = each_result.find(static_cast<int>(kind));
233  if (result != each_result.end()) {
234  return result->second;
235  } else {
236  return nullptr;
237  }
238  }
239 
240 
241  private:
242  DenseMap<int, VerifyResultBase*> each_result;
243 
250  bool bool_operator_impl() override;
251 
252  DenseMap<Loop*,BranchInst*> back_branch_list;
253 
254  };
255 
261  private:
262  SmallVector<Loop*> valid_kernels;
263 
264  public:
265  using KernelList = SmallVector<Loop*>;
266  using kernel_iterator = KernelList::iterator;
267 
272  void print(raw_ostream &OS) const override;
273 
278  void registerKernel(Loop *L, LoopVerifyResult LVR) {
279  valid_kernels.push_back(L);
280  loop_verify_results[L] = LVR;
281  }
282 
284  return valid_kernels.begin();
285  };
286 
288  return valid_kernels.end();
289  }
290  inline iterator_range<kernel_iterator> kernels() {
291  return make_range(kernel_begin(), kernel_end());
292  }
293  static bool classof(const VerifyResultBase* R) {
294  return R->getKind() == VerificationKind::FunctionSummary;
295  }
296 
298  if (loop_verify_results.find(L) != loop_verify_results.end()) {
299  return &loop_verify_results[L];
300  } else {
301  return nullptr;
302  }
303  }
304 
305  StringRef getName() const {
306  return "Verify result summary";
307  }
308 
310  return valid_kernels.size();
311  }
312 
313 
314  private:
315  std::map<Loop*, LoopVerifyResult> loop_verify_results;
316  };
317 
323  template<VerificationKind Kind>
325  public:
327  SimpleVerifyResult(std::string msg) : VerifyResultBase(Kind),
328  msg(msg) {};
329 
330  void setMessage(StringRef msg) {
331  msg = msg.str();
332  }
333  void print(raw_ostream &OS) const {
334  OS << msg;
335  }
336 
337  StringRef getName() const {
338  return name;
339  }
340 
341  private:
342  std::string msg;
343  static const char *name;
344  };
345 
348 
354  template <typename DerivedT>
355  class VerifyPassBase : public AnalysisInfoMixin<DerivedT> {
356  public:
357  using LoopList = SmallVector<Loop*>;
358  // using InstList = SmallVector<Instruction*>;
359  protected:
360 
370  LoopList findPerfectlyNestedLoop(Function &F,
371  LoopStandardAnalysisResults &AR);
372 
373  void remarkEmitter(Function &F, Loop &L, LoopVerifyResult &R,
374  FunctionAnalysisManager &AM);
375  };
376 
382  public VerifyPassBase<TimeMultiplexedVerifyPass> {
383  public:
385  Result run(Function &F, FunctionAnalysisManager &AM);
386  private:
387  friend AnalysisInfoMixin<TimeMultiplexedVerifyPass>;
388  static AnalysisKey Key;
389 
390  };
391 
392 
398  public VerifyPassBase<DecoupledVerifyPass> {
399  public:
401  Result run(Function &F, FunctionAnalysisManager &AM);
402  private:
403  friend AnalysisInfoMixin<DecoupledVerifyPass>;
404  static AnalysisKey Key;
405 
406 
407  };
408 
410  public:
413 
414  void filter(SmallVector<Instruction*> *list);
415  void filter(SmallPtrSetImpl<Instruction*> *list);
416 
417  void print(raw_ostream &OS) const override;
418 
419  void add_unsupported(Instruction* I) {
420  unsupported.insert(I);
421  }
422 
423  StringRef getName() const {
424  return "Instruction availability";
425  }
426 
427  private:
434  bool bool_operator_impl() override {
435  return unsupported.size() == 0;
436  }
437 
438  SmallPtrSet<Instruction*, 32> unsupported;
439  };
440 
448  template <typename VerifyPassTy>
450  public AnalysisInfoMixin<VerifyInstAvailabilityPass<VerifyPassTy>> {
451  public:
453 
454  Result run(Loop &L, LoopAnalysisManager &AM,
455  LoopStandardAnalysisResults &AR) {
456 
457  #define DEBUG_TYPE "cgraomp"
458  LLVM_DEBUG(dbgs() << INFO_DEBUG_PREFIX
459  << "Verifying insturction compatibility: "
460  << L.getName() << "\n");
461  #undef DEBUG_TYPE
462 
463  auto unsupported_insts = checkUnsupportedInst(L, AM, AR);
464  Result result;
465 
466  if (unsupported_insts.hasValue()) {
467  // Invalid
468  for (auto inst : *unsupported_insts) {
469  result.add_unsupported(inst);
470  }
471  }
472  return result;
473  };
474 
475  private:
476  friend AnalysisInfoMixin<VerifyInstAvailabilityPass<VerifyPassTy>>;
477  static AnalysisKey Key;
478  using InstList = SmallVector<Instruction*>;
479 
490  Optional<InstList>
491  checkUnsupportedInst(Loop& L, LoopAnalysisManager &AM,
492  LoopStandardAnalysisResults &AR)
493  {
494  auto LN = LoopNest::getLoopNest(L, AR.SE);
495  auto innermost = LN->getInnermostLoop();
496 
497  auto &MM = AM.getResult<ModelManagerLoopProxy>(L, AR);
498  auto *model = MM.getModel();
499 
500  InstList unsupported;
501 
502  for (auto &BB : innermost->getBlocks()) {
503  for (auto &I : *BB) {
504  auto *imap = model->isSupported(&I);
505  if (!imap) {
506  unsupported.emplace_back(&I);
507  }
508  }
509  }
510 
511  if (unsupported.size() == 0) {
512  return None;
513  } else {
514  return Optional<InstList>(std::move(unsupported));
515  }
516  }
517 
518  };
519 
520  template <typename VerifyPassTy>
521  AnalysisKey VerifyInstAvailabilityPass<VerifyPassTy>::Key;
522 
523 
528  class VerifyModulePass : public PassInfoMixin<VerifyModulePass> {
529  public:
530  PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
531  private:
532  void remarkEmitter(Function &F, VerifyResult &R,
533  FunctionAnalysisManager &AM);
534  };
535 
536 }
537 
538 #endif //VerifyPass_H
CGRAOmp::InstAvailability
Definition: VerifyPass.hpp:409
CGRAOmp::VerificationKind::InterLoopDep
@ InterLoopDep
Checking the loop has inter-loop-dependency.
llvm
Definition: OptionPlugin.cpp:128
CGRAOmp::VerifyResult::kernels
iterator_range< kernel_iterator > kernels()
Definition: VerifyPass.hpp:290
CGRAOmp::VerifyResult::kernel_iterator
KernelList::iterator kernel_iterator
Definition: VerifyPass.hpp:266
CGRAOmp::VerificationKind::FunctionCall
@ FunctionCall
Checking if the loop contains function call.
CGRAOmp::InstAvailability::bool_operator_impl
bool bool_operator_impl() override
bool_operator
Definition: VerifyPass.hpp:434
CGRAOmp::SimpleVerifyResult::SimpleVerifyResult
SimpleVerifyResult()
Definition: VerifyPass.hpp:326
CGRAOmp::VerifyResultBase
An abstract class for the verification information.
Definition: VerifyPass.hpp:96
CGRAOmp::SimpleVerifyResult::msg
std::string msg
Definition: VerifyPass.hpp:342
CGRAOmp::VerifyResultBase::getKind
virtual VerificationKind getKind() const
get the kind of derived class
Definition: VerifyPass.hpp:149
CGRAOmp::VerifyResultBase::bool_operator_impl
virtual bool bool_operator_impl()
An actual impelementation for casting to Boolean.
Definition: VerifyPass.hpp:157
CGRAOmp::VerifyResult::getName
StringRef getName() const
Definition: VerifyPass.hpp:305
CGRAModel.hpp
CGRAOmp::InstAvailability::InstAvailability
InstAvailability()
Definition: VerifyPass.hpp:411
CGRAOmp::SimpleVerifyResult::name
static const char * name
Definition: VerifyPass.hpp:343
INFO_DEBUG_PREFIX
#define INFO_DEBUG_PREFIX
Definition: common.hpp:39
CGRAOmp::DecoupledVerifyPass
A function pass to verify the kernel for Decoupled CGRA.
Definition: VerifyPass.hpp:397
CGRAOmp::VerificationKind::Conditional
@ Conditional
Checking if the loop contains condional part or not.
CGRAOmp::DecoupledVerifyPass::Key
static AnalysisKey Key
Definition: VerifyPass.hpp:404
CGRAOmp::VerifyResult::loop_verify_results
std::map< Loop *, LoopVerifyResult > loop_verify_results
Definition: VerifyPass.hpp:315
CGRAOmp::VerificationKind::MemoryAccess
@ MemoryAccess
Checking each memory access meets the allowed access pattern.
CGRAOmp::VerifyResultBase::print
virtual void print(raw_ostream &OS) const =0
An abstract method to print the verification result.
CGRAOmp::VerifyPassBase< TimeMultiplexedVerifyPass >::LoopList
SmallVector< Loop * > LoopList
Definition: VerifyPass.hpp:357
CGRAOmpPass.hpp
CGRAOmp::VerifyResult::classof
static bool classof(const VerifyResultBase *R)
Definition: VerifyPass.hpp:293
CGRAOmp::VerifyInstAvailabilityPass::checkUnsupportedInst
Optional< InstList > checkUnsupportedInst(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR)
default routine to check whether the kernel contains unspported instructions
Definition: VerifyPass.hpp:491
CGRAOmp::LoopVerifyResult::getBackCondition
CmpInst * getBackCondition(Loop *L)
Definition: VerifyPass.hpp:203
CGRAOmp::VerifyResult::kernel_end
kernel_iterator kernel_end()
Definition: VerifyPass.hpp:287
CGRAOmp::VerifyResult::valid_kernels
SmallVector< Loop * > valid_kernels
Definition: VerifyPass.hpp:262
CGRAOmp::VerificationKind::FunctionSummary
@ FunctionSummary
Summary of the verfication for a function including kernels.
CGRAOmp::LoopVerifyResult::LoopVerifyResult
LoopVerifyResult()
Construct a new Verify Result object.
Definition: VerifyPass.hpp:180
CGRAOmp::VerificationKind::KernelSummary
@ KernelSummary
Summary of the loop verification.
DecoupledAnalysis.hpp
CGRAOmp::LoopVerifyResult::setBackBranch
void setBackBranch(Loop *L, BranchInst *B)
Definition: VerifyPass.hpp:211
CGRAOmp::TimeMultiplexedVerifyPass
A function pass to verify the kernel for TimeMultiplexed CGRA.
Definition: VerifyPass.hpp:381
CGRAOmp::VerifyResultBase::dump
void dump()
dump the verification result like as debugging in LLVM
Definition: VerifyPass.hpp:128
CGRAOmp::SimpleVerifyResult
Simple verification result only with a verification message.
Definition: VerifyPass.hpp:324
CGRAOmp::VerifyResult::KernelList
SmallVector< Loop * > KernelList
Definition: VerifyPass.hpp:265
CGRAOmp::VerifyResultBase::setVio
void setVio()
mark this result as violated
Definition: VerifyPass.hpp:143
CGRAOmp::SimpleVerifyResult::setMessage
void setMessage(StringRef msg)
Definition: VerifyPass.hpp:330
CGRAOmp
Definition: AGVerifyPass.hpp:50
CGRAOmp::VerifyInstAvailabilityPass
A template class for verify the instruction availability It is possible to customize the routine with...
Definition: VerifyPass.hpp:449
CGRAOmp::LoopVerifyResult::getName
StringRef getName() const
Definition: VerifyPass.hpp:227
CGRAOmp::VerifyResult
A derived class from VerifyResultBase bunding all kernel verification result.
Definition: VerifyPass.hpp:260
CGRAOmp::LoopVerifyResult
A derived class from VerifyResultBase bundling detailed results for each verification type.
Definition: VerifyPass.hpp:172
CGRAOmp::LoopVerifyResult::result_begin
result_iterator result_begin()
Definition: VerifyPass.hpp:215
CGRAOmp::LoopVerifyResult::getBackBranch
BranchInst * getBackBranch(Loop *L)
Definition: VerifyPass.hpp:195
CGRAOmp::LoopVerifyResult::setResult
void setResult(VerifyResultBase *R)
Set the verification result for a kind of rule.
Definition: VerifyPass.hpp:191
CGRAOmp::SimpleVerifyResult::SimpleVerifyResult
SimpleVerifyResult(std::string msg)
Definition: VerifyPass.hpp:327
CGRAOmp::VerificationKind::MaxNestedLevel
@ MaxNestedLevel
Checking the kernel exceeds the maximumn nested level.
CGRAOmp::VerifyResult::kernel_begin
kernel_iterator kernel_begin()
Definition: VerifyPass.hpp:283
CGRAOmp::VerificationKind::Decoupling
@ Decoupling
Checking the loop kernel is able to be decoupled.
CGRAOmp::VerificationKind::IterationSize
@ IterationSize
CGRAOmp::VerifyResultBase::kind
VerificationKind kind
Definition: VerifyPass.hpp:164
CGRAOmp::TimeMultiplexedVerifyPass::Key
static AnalysisKey Key
Definition: VerifyPass.hpp:388
CGRAOmp::VerifyResult::getNumKernels
int getNumKernels()
Definition: VerifyPass.hpp:309
CGRAOmp::LoopVerifyResult::result_iterator
DenseMap< int, VerifyResultBase * >::iterator result_iterator
Definition: VerifyPass.hpp:175
CGRAOmp::VerifyInstAvailabilityPass::InstList
SmallVector< Instruction * > InstList
Definition: VerifyPass.hpp:478
CGRAOmp::LoopVerifyResult::classof
static bool classof(const VerifyResultBase *R)
Definition: VerifyPass.hpp:183
CGRAOmp::VerifyResult::VerifyResult
VerifyResult()
Construct a new Verify Result object.
Definition: VerifyPass.hpp:271
CGRAOmp::InstAvailability::unsupported
SmallPtrSet< Instruction *, 32 > unsupported
Definition: VerifyPass.hpp:438
CGRAOmp::ModelManagerLoopProxy
A proxy to access model manager from loop passes.
Definition: CGRAOmpPass.hpp:136
CGRAOmp::VerifyModulePass
A module pass to verify all annotated functions.
Definition: VerifyPass.hpp:528
CGRAOmp::LoopVerifyResult::result_end
result_iterator result_end()
Definition: VerifyPass.hpp:219
CGRAOmp::SimpleVerifyResult::print
void print(raw_ostream &OS) const
An abstract method to print the verification result.
Definition: VerifyPass.hpp:333
CGRAOmp::VerifyInstAvailabilityPass::run
Result run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR)
Definition: VerifyPass.hpp:454
CGRAOmp::VerifyResultBase::VerifyResultBase
VerifyResultBase(VerificationKind kind)
Construct a new Verify Result Base object.
Definition: VerifyPass.hpp:101
CGRAOmp::VerifyPassBase
a template for verification pass
Definition: VerifyPass.hpp:355
CGRAOmp::VerifyInstAvailabilityPass::Key
static AnalysisKey Key
Definition: VerifyPass.hpp:477
CGRAOmp::LoopVerifyResult::results
iterator_range< result_iterator > results()
Definition: VerifyPass.hpp:223
CGRAOmp::InstAvailability::add_unsupported
void add_unsupported(Instruction *I)
Definition: VerifyPass.hpp:419
CGRAOmp::VerifyResult::registerKernel
void registerKernel(Loop *L, LoopVerifyResult LVR)
register a valid loop kernel for the target CGRA
Definition: VerifyPass.hpp:278
CGRAOmp::VerificationKind::NestedPerfectly
@ NestedPerfectly
Checking if the loop nested structure is perfectly nested or not.
CGRAOmp::LoopVerifyResult::each_result
DenseMap< int, VerifyResultBase * > each_result
Definition: VerifyPass.hpp:242
CGRAOmp::SimpleVerifyResult::getName
StringRef getName() const
Definition: VerifyPass.hpp:337
CGRAOmp::VerifyResultBase::operator<<
friend raw_ostream & operator<<(raw_ostream &OS, const VerifyResultBase &v)
support << operator to show the verification result
Definition: VerifyPass.hpp:132
CGRAOmp::InstAvailability::getName
StringRef getName() const
Definition: VerifyPass.hpp:423
CGRAOmp::VerificationKind
VerificationKind
Kind of verification.
Definition: VerifyPass.hpp:64
CGRAOmp::LoopVerifyResult::back_branch_list
DenseMap< Loop *, BranchInst * > back_branch_list
Definition: VerifyPass.hpp:252
CGRAOmp::VerifyResult::getLoopVerifyResult
LoopVerifyResult * getLoopVerifyResult(Loop *L)
Definition: VerifyPass.hpp:297
CGRAOmp::LoopVerifyResult::getResult
VerifyResultBase * getResult(VerificationKind kind)
Definition: VerifyPass.hpp:231