コード例 #1
0
ファイル: BlockGenerators.cpp プロジェクト: fangism/polly
void VectorBlockGenerator::copyStmt(ScopStmt &Stmt) {
  assert(Stmt.isBlockStmt() && "TODO: Only block statements can be copied by "
                               "the vector block generator");

  BasicBlock *BB = Stmt.getBasicBlock();
  BasicBlock *CopyBB =
      SplitBlock(Builder.GetInsertBlock(), Builder.GetInsertPoint(), &DT, &LI);
  CopyBB->setName("polly.stmt." + BB->getName());
  Builder.SetInsertPoint(CopyBB->begin());

  // Create two maps that store the mapping from the original instructions of
  // the old basic block to their copies in the new basic block. Those maps
  // are basic block local.
  //
  // As vector code generation is supported there is one map for scalar values
  // and one for vector values.
  //
  // In case we just do scalar code generation, the vectorMap is not used and
  // the scalarMap has just one dimension, which contains the mapping.
  //
  // In case vector code generation is done, an instruction may either appear
  // in the vector map once (as it is calculating >vectorwidth< values at a
  // time. Or (if the values are calculated using scalar operations), it
  // appears once in every dimension of the scalarMap.
  VectorValueMapT ScalarBlockMap(getVectorWidth());
  ValueMapT VectorBlockMap;

  for (Instruction &Inst : *BB)
    copyInstruction(Stmt, &Inst, VectorBlockMap, ScalarBlockMap);
}
コード例 #2
0
ファイル: BlockGenerators.cpp プロジェクト: fangism/polly
void BlockGenerator::copyStmt(ScopStmt &Stmt, ValueMapT &GlobalMap,
                              LoopToScevMapT &LTS) {
  assert(Stmt.isBlockStmt() &&
         "Only block statements can be copied by the block generator");

  ValueMapT BBMap;

  BasicBlock *BB = Stmt.getBasicBlock();
  copyBB(Stmt, BB, BBMap, GlobalMap, LTS);
}
コード例 #3
0
ファイル: BlockGenerators.cpp プロジェクト: fangism/polly
void BlockGenerator::generateScalarStores(ScopStmt &Stmt, BasicBlock *BB,
                                          ValueMapT &BBMap,
                                          ValueMapT &GlobalMap) {
  const Region &R = Stmt.getParent()->getRegion();

  assert(Stmt.isBlockStmt() && BB == Stmt.getBasicBlock() &&
         "Region statements need to use the generateScalarStores() "
         "function in the RegionGenerator");

  // Set to remember a store to the phiops alloca of a PHINode. It is needed as
  // we might have multiple write accesses to the same PHI and while one is the
  // self write of the PHI (to the ScalarMap alloca) the other is the write to
  // the operand alloca (PHIOpMap).
  SmallPtrSet<PHINode *, 4> SeenPHIs;

  // Iterate over all accesses in the given statement.
  for (MemoryAccess *MA : Stmt) {

    // Skip non-scalar and read accesses.
    if (!MA->isScalar() || MA->isRead())
      continue;

    Instruction *ScalarBase = cast<Instruction>(MA->getBaseAddr());
    Instruction *ScalarInst = MA->getAccessInstruction();
    PHINode *ScalarBasePHI = dyn_cast<PHINode>(ScalarBase);

    // Get the alloca node for the base instruction and the value we want to
    // store. In total there are 4 options:
    //  (1) The base is no PHI, hence it is a simple scalar def-use chain.
    //  (2) The base is a PHI,
    //      (a) and the write is caused by an operand in the block.
    //      (b) and it is the PHI self write (same as case (1)).
    //      (c) (2a) and (2b) are not distinguishable.
    // For case (1) and (2b) we get the alloca from the scalar map and the value
    // we want to store is initialized with the instruction attached to the
    // memory access. For case (2a) we get the alloca from the PHI operand map
    // and the value we want to store is initialized with the incoming value for
    // this block. The tricky case (2c) is when both (2a) and (2b) match. This
    // happens if the PHI operand is in the same block as the PHI. To handle
    // that we choose the alloca of (2a) first and (2b) for the next write
    // access to that PHI (there must be 2).
    Value *ScalarValue = nullptr;
    AllocaInst *ScalarAddr = nullptr;

    if (!ScalarBasePHI) {
      // Case (1)
      ScalarAddr = getOrCreateAlloca(ScalarBase, ScalarMap, ".s2a");
      ScalarValue = ScalarInst;
    } else {
      int PHIIdx = ScalarBasePHI->getBasicBlockIndex(BB);
      if (ScalarBasePHI != ScalarInst) {
        // Case (2a)
        assert(PHIIdx >= 0 && "Bad scalar write to PHI operand");
        SeenPHIs.insert(ScalarBasePHI);
        ScalarAddr = getOrCreateAlloca(ScalarBase, PHIOpMap, ".phiops");
        ScalarValue = ScalarBasePHI->getIncomingValue(PHIIdx);
      } else if (PHIIdx < 0) {
        // Case (2b)
        ScalarAddr = getOrCreateAlloca(ScalarBase, ScalarMap, ".s2a");
        ScalarValue = ScalarInst;
      } else {
        // Case (2c)
        if (SeenPHIs.insert(ScalarBasePHI).second) {
          // First access ==> same as (2a)
          ScalarAddr = getOrCreateAlloca(ScalarBase, PHIOpMap, ".phiops");
          ScalarValue = ScalarBasePHI->getIncomingValue(PHIIdx);
        } else {
          // Second access ==> same as (2b)
          ScalarAddr = getOrCreateAlloca(ScalarBase, ScalarMap, ".s2a");
          ScalarValue = ScalarInst;
        }
      }
    }

    ScalarValue =
        getNewScalarValue(ScalarValue, R, ScalarMap, BBMap, GlobalMap);
    Builder.CreateStore(ScalarValue, ScalarAddr);
  }
}