Пример #1
0
Stmt *TransformVector::VisitConditionalOperator(ConditionalOperator *Node) {
  Expr *Cond = Node->getCond();
  QualType CondTy = Cond->getType();
  Expr *LHS = Node->getLHS();
  Expr *RHS = Node->getRHS();

  if (CondTy->isVectorType()) {
    // If the type of Cond is a vector type, change this expr to select().
    DeclVector DeclVec;
    Cond = ConvertVecLiteralInExpr(DeclVec, Cond);
    LHS = ConvertVecLiteralInExpr(DeclVec, LHS);
    RHS = ConvertVecLiteralInExpr(DeclVec, RHS);

    if (DeclVec.size() > 0) {
      PushBackDeclStmts(*CurStmtVec, DeclVec);
    }

    QualType NodeTy = Node->getType();

    ASTCtx.Deallocate(Node);

    Expr *Args[3] = { RHS, LHS, Cond };
    return new (ASTCtx) CallExpr(ASTCtx, 
        CLExprs.getExpr(CLExpressions::SELECT), Args, 3, NodeTy, 
        VK_RValue, SourceLocation());
  } else {
    Node->setCond(TransformExpr(Cond));
    Node->setLHS(TransformExpr(LHS));
    Node->setRHS(TransformExpr(RHS));
  }
  return Node;
}
Пример #2
0
static bool isTrackedVar(const VarDecl *vd, const DeclContext *dc) {
  if (vd->isLocalVarDecl() && !vd->hasGlobalStorage() &&
      !vd->isExceptionVariable() &&
      vd->getDeclContext() == dc) {
    QualType ty = vd->getType();
    return ty->isScalarType() || ty->isVectorType();
  }
  return false;
}
Пример #3
0
void TransformVector::TransformVectorLiteralExpr(
    CompoundLiteralExpr *E, Expr **Args, unsigned StartPos) {
  InitListExpr *ILE = dyn_cast<InitListExpr>(E->getInitializer());
  assert(ILE && "ERROR: Vector literal is not an InitListExpr");

  QualType ETy = E->getType();
  const ExtVectorType *EVT = ETy->getAs<ExtVectorType>();
  unsigned NumElems = EVT->getNumElements();
  unsigned VecPos   = 0;
  bool HasOneInitElem = (ILE->getNumInits() == 1);

  for (unsigned i = StartPos; i < StartPos + NumElems; i++) {
    Expr *InitExpr = ILE->getInit(VecPos);
    if (!HasOneInitElem) VecPos++;
    if (InitExpr == NULL) {
      // zero
      Args[i] = CLExprs.getExpr(CLExpressions::ZERO);
      continue;
    }

    QualType InitType = InitExpr->getType();
    if (!InitType->isVectorType()) {
      // scalar element
      Args[i] = TransformExpr(InitExpr);
      continue;
    }

    // vector element
    const ExtVectorType *InitVec = InitType->getAs<ExtVectorType>();
    unsigned InitNumElems = InitVec->getNumElements();

    // Strip off any ParenExpr or CastExprs
    InitExpr = InitExpr->IgnoreParenCasts();
    if (CompoundLiteralExpr *CE = dyn_cast<CompoundLiteralExpr>(InitExpr)) {
      TransformVectorLiteralExpr(CE, Args, i);
      i += (InitNumElems - 1);
    } else {
      CLExpressions::ExprKind kind;
      for (unsigned t = 0; t < InitNumElems; ++t, ++i) {
        // ArraySubscriptExpr
        kind = (CLExpressions::ExprKind)(CLExpressions::ZERO + t);
        Args[i] = new (ASTCtx) ArraySubscriptExpr(
            InitExpr, CLExprs.getExpr(kind), 
            InitType, VK_RValue, OK_Ordinary, SourceLocation());
      }
      --i;
    }
  }

  ASTCtx.Deallocate(ILE);
  ASTCtx.Deallocate(E);
}
Пример #4
0
// get read_image function for given Accessor
FunctionDecl *ASTTranslate::getImageFunction(HipaccAccessor *Acc, MemoryAccess
    mem_acc) {
  QualType QT = Acc->getImage()->getType();

  if (QT->isVectorType()) {
      QT = QT->getAs<VectorType>()->getElementType();
  }
  const BuiltinType *BT = QT->getAs<BuiltinType>();

  switch (BT->getKind()) {
    case BuiltinType::WChar_U:
    case BuiltinType::WChar_S:
    case BuiltinType::ULongLong:
    case BuiltinType::UInt128:
    case BuiltinType::LongLong:
    case BuiltinType::Int128:
    case BuiltinType::LongDouble:
    case BuiltinType::Void:
    case BuiltinType::Bool:
    case BuiltinType::Long:
    case BuiltinType::ULong:
    case BuiltinType::Double:
    default:
      assert(0 && "BuiltinType for OpenCL Image not supported.");
    case BuiltinType::Char_S:
    case BuiltinType::SChar:
    case BuiltinType::Short:
    case BuiltinType::Int:
      if (mem_acc==READ_ONLY) {
        return builtins.getBuiltinFunction(OPENCLBIread_imagei);
      } else {
        return builtins.getBuiltinFunction(OPENCLBIwrite_imagei);
      }
    case BuiltinType::Char_U:
    case BuiltinType::UChar:
    case BuiltinType::Char16:
    case BuiltinType::UShort:
    case BuiltinType::Char32:
    case BuiltinType::UInt:
      if (mem_acc==READ_ONLY) {
        return builtins.getBuiltinFunction(OPENCLBIread_imageui);
      } else {
        return builtins.getBuiltinFunction(OPENCLBIwrite_imageui);
      }
    case BuiltinType::Float:
      if (mem_acc==READ_ONLY) {
        return builtins.getBuiltinFunction(OPENCLBIread_imagef);
      } else {
        return builtins.getBuiltinFunction(OPENCLBIwrite_imagef);
      }
  }
}
Пример #5
0
DefinedOrUnknownSVal SValBuilder::makeZeroVal(QualType type) {
  if (Loc::isLocType(type))
    return makeNull();

  if (type->isIntegralOrEnumerationType())
    return makeIntVal(0, type);

  if (type->isArrayType() || type->isRecordType() || type->isVectorType() ||
      type->isAnyComplexType())
    return makeCompoundVal(type, BasicVals.getEmptySValList());

  // FIXME: Handle floats.
  return UnknownVal();
}
Пример #6
0
void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
                                   ExplodedNode *Pred,
                                   ExplodedNodeSet &Dst) {
  StmtNodeBuilder B(Pred, Dst, *currBldrCtx);

  ProgramStateRef state = Pred->getState();
  const LocationContext *LCtx = Pred->getLocationContext();
  QualType T = getContext().getCanonicalType(IE->getType());
  unsigned NumInitElements = IE->getNumInits();

  if (!IE->isGLValue() &&
      (T->isArrayType() || T->isRecordType() || T->isVectorType() ||
       T->isAnyComplexType())) {
    llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList();

    // Handle base case where the initializer has no elements.
    // e.g: static int* myArray[] = {};
    if (NumInitElements == 0) {
      SVal V = svalBuilder.makeCompoundVal(T, vals);
      B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
      return;
    }

    for (InitListExpr::const_reverse_iterator it = IE->rbegin(),
         ei = IE->rend(); it != ei; ++it) {
      SVal V = state->getSVal(cast<Expr>(*it), LCtx);
      vals = getBasicVals().prependSVal(V, vals);
    }

    B.generateNode(IE, Pred,
                   state->BindExpr(IE, LCtx,
                                   svalBuilder.makeCompoundVal(T, vals)));
    return;
  }

  // Handle scalars: int{5} and int{} and GLvalues.
  // Note, if the InitListExpr is a GLvalue, it means that there is an address
  // representing it, so it must have a single init element.
  assert(NumInitElements <= 1);

  SVal V;
  if (NumInitElements == 0)
    V = getSValBuilder().makeZeroVal(T);
  else
    V = state->getSVal(IE->getInit(0), LCtx);

  B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
}
Пример #7
0
void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
                                   ExplodedNode *Pred,
                                   ExplodedNodeSet &Dst) {
  StmtNodeBuilder B(Pred, Dst, *currBldrCtx);

  ProgramStateRef state = Pred->getState();
  const LocationContext *LCtx = Pred->getLocationContext();
  QualType T = getContext().getCanonicalType(IE->getType());
  unsigned NumInitElements = IE->getNumInits();
  
  if (T->isArrayType() || T->isRecordType() || T->isVectorType() ||
      T->isAnyComplexType()) {
    llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList();
    
    // Handle base case where the initializer has no elements.
    // e.g: static int* myArray[] = {};
    if (NumInitElements == 0) {
      SVal V = svalBuilder.makeCompoundVal(T, vals);
      B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
      return;
    }
    
    for (InitListExpr::const_reverse_iterator it = IE->rbegin(),
         ei = IE->rend(); it != ei; ++it) {
      SVal V = state->getSVal(cast<Expr>(*it), LCtx);
      if (dyn_cast_or_null<CXXTempObjectRegion>(V.getAsRegion()))
        V = UnknownVal();
      vals = getBasicVals().consVals(V, vals);
    }
    
    B.generateNode(IE, Pred,
                   state->BindExpr(IE, LCtx,
                                   svalBuilder.makeCompoundVal(T, vals)));
    return;
  }

  // Handle scalars: int{5} and int{}.
  assert(NumInitElements <= 1);

  SVal V;
  if (NumInitElements == 0)
    V = getSValBuilder().makeZeroVal(T);
  else
    V = state->getSVal(IE->getInit(0), LCtx);

  B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
}
Пример #8
0
Stmt *TransformVector::VisitCStyleCastExpr(CStyleCastExpr *Node) {
  QualType NodeTy = Node->getType();
  Expr *SubExpr = TransformExpr(Node->getSubExpr());

  // If the type of Node is a vector type, add a vector conversion function.
  if (NodeTy->isVectorType()) {
    ASTCtx.Deallocate(Node);

    SourceLocation loc;
    Expr *args[1] = { SubExpr };
    return new (ASTCtx) CallExpr(ASTCtx, 
        CLExprs.getConvertExpr(NodeTy), args, 1, NodeTy, VK_RValue, loc);
  }

  Node->setSubExpr(SubExpr);
  return Node;
}
Пример #9
0
// Based on QualType::isTrivial.
bool isTriviallyDefaultConstructible(QualType Type, const ASTContext &Context) {
  if (Type.isNull())
    return false;

  if (Type->isArrayType())
    return isTriviallyDefaultConstructible(Context.getBaseElementType(Type),
                                           Context);

  // Return false for incomplete types after skipping any incomplete array
  // types which are expressly allowed by the standard and thus our API.
  if (Type->isIncompleteType())
    return false;

  if (Context.getLangOpts().ObjCAutoRefCount) {
    switch (Type.getObjCLifetime()) {
    case Qualifiers::OCL_ExplicitNone:
      return true;

    case Qualifiers::OCL_Strong:
    case Qualifiers::OCL_Weak:
    case Qualifiers::OCL_Autoreleasing:
      return false;

    case Qualifiers::OCL_None:
      if (Type->isObjCLifetimeType())
        return false;
      break;
    }
  }

  QualType CanonicalType = Type.getCanonicalType();
  if (CanonicalType->isDependentType())
    return false;

  // As an extension, Clang treats vector types as Scalar types.
  if (CanonicalType->isScalarType() || CanonicalType->isVectorType())
    return true;

  if (const auto *RT = CanonicalType->getAs<RecordType>()) {
    return recordIsTriviallyDefaultConstructible(*RT->getDecl(), Context);
  }

  // No other types can match.
  return false;
}
Пример #10
0
void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
                                   ExplodedNode *Pred,
                                   ExplodedNodeSet &Dst) {
  StmtNodeBuilder B(Pred, Dst, *currentBuilderContext);

  const ProgramState *state = Pred->getState();
  const LocationContext *LCtx = Pred->getLocationContext();
  QualType T = getContext().getCanonicalType(IE->getType());
  unsigned NumInitElements = IE->getNumInits();
  
  if (T->isArrayType() || T->isRecordType() || T->isVectorType()) {
    llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList();
    
    // Handle base case where the initializer has no elements.
    // e.g: static int* myArray[] = {};
    if (NumInitElements == 0) {
      SVal V = svalBuilder.makeCompoundVal(T, vals);
      B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
      return;
    }
    
    for (InitListExpr::const_reverse_iterator it = IE->rbegin(),
         ei = IE->rend(); it != ei; ++it) {
      vals = getBasicVals().consVals(state->getSVal(cast<Expr>(*it), LCtx),
                                     vals);
    }
    
    B.generateNode(IE, Pred,
                   state->BindExpr(IE, LCtx,
                                   svalBuilder.makeCompoundVal(T, vals)));
    return;
  }
  
  if (Loc::isLocType(T) || T->isIntegerType()) {
    assert(IE->getNumInits() == 1);
    const Expr *initEx = IE->getInit(0);
    B.generateNode(IE, Pred, state->BindExpr(IE, LCtx,
                                             state->getSVal(initEx, LCtx)));
    return;
  }
  
  llvm_unreachable("unprocessed InitListExpr type");
}
Пример #11
0
void HipaccBoundaryCondition::setConstVal(APValue &val, ASTContext &Ctx) {
  QualType QT = getImage()->getType();

  bool isVecType = QT->isVectorType();
  if (isVecType) {
      QT = QT->getAs<VectorType>()->getElementType();
  }
  const BuiltinType *BT = QT->getAs<BuiltinType>();

  switch (BT->getKind()) {
    case BuiltinType::WChar_S:
    case BuiltinType::WChar_U:
    case BuiltinType::ULongLong:
    case BuiltinType::UInt128:
    case BuiltinType::LongLong:
    case BuiltinType::Int128:
    case BuiltinType::LongDouble:
    case BuiltinType::Void:
    case BuiltinType::Bool:
    default:
      assert(0 && "BuiltinType for Boundary handling constant not supported.");
    case BuiltinType::Char_S:
    case BuiltinType::SChar:
    case BuiltinType::Char_U:
    case BuiltinType::UChar:
      if (isVecType) {
        SmallVector<Expr *, 16> initExprs;

        for (size_t I=0, N=val.getVectorLength(); I!=N; ++I) {
          APValue lane = val.getVectorElt(I);
          initExprs.push_back(new (Ctx)
              CharacterLiteral(lane.getInt().getSExtValue(),
                CharacterLiteral::Ascii, QT, SourceLocation()));
        }

        constExpr = new (Ctx) InitListExpr(Ctx, SourceLocation(),
            llvm::makeArrayRef(initExprs.data(), initExprs.size()),
            SourceLocation());
        constExpr->setType(getImage()->getType());
      } else {
        constExpr = new (Ctx) CharacterLiteral(val.getInt().getSExtValue(),
            CharacterLiteral::Ascii, QT, SourceLocation());
      }
      break;
    case BuiltinType::Char16:
    case BuiltinType::Char32:
    case BuiltinType::Short:
    case BuiltinType::UShort:
    case BuiltinType::Int:
    case BuiltinType::UInt:
    case BuiltinType::Long:
    case BuiltinType::ULong:
      if (isVecType) {
        SmallVector<Expr *, 16> initExprs;

        for (size_t I=0, N=val.getVectorLength(); I!=N; ++I) {
          APValue lane = val.getVectorElt(I);
          initExprs.push_back(new (Ctx) IntegerLiteral(Ctx, lane.getInt(), QT,
                SourceLocation()));
        }

        constExpr = new (Ctx) InitListExpr(Ctx, SourceLocation(),
            llvm::makeArrayRef(initExprs.data(), initExprs.size()),
            SourceLocation());
        constExpr->setType(getImage()->getType());
      } else {
        constExpr = new (Ctx) IntegerLiteral(Ctx, val.getInt(), QT,
            SourceLocation());
      }
      break;
    case BuiltinType::Float:
    case BuiltinType::Double:
      if (isVecType) {
        SmallVector<Expr *, 16> initExprs;

        for (size_t I=0, N=val.getVectorLength(); I!=N; ++I) {
          APValue lane = val.getVectorElt(I);
          initExprs.push_back(FloatingLiteral::Create(Ctx,
                llvm::APFloat(lane.getFloat()), false, QT, SourceLocation()));
        }

        constExpr = new (Ctx) InitListExpr(Ctx, SourceLocation(),
            llvm::makeArrayRef(initExprs.data(), initExprs.size()),
            SourceLocation());
        constExpr->setType(getImage()->getType());
      } else {
        constExpr = FloatingLiteral::Create(Ctx, llvm::APFloat(val.getFloat()),
            false, QT, SourceLocation());
      }
      break;
  }
}
Пример #12
0
Expr *TransformVector::ConvertAssignExpr(DeclVector &DeclVec,
                                         ExtVectorElementExpr *LHS,
                                         BinaryOperator::Opcode Op,
                                         Expr *BRHS) {
  QualType BRHSTy = BRHS->getType();
  Expr *RHS = BRHS->IgnoreParenCasts();
  if (!(isa<CompoundLiteralExpr>(RHS) || isa<ExtVectorElementExpr>(RHS))) {
    RHS = ConvertVecLiteralInExpr(DeclVec, RHS);

    QualType RHSTy = RHS->getType();
    if (RHSTy->isVectorType() && !isa<DeclRefExpr>(RHS)) {
      // Make a VarDecl with RHS
      VarDecl *VD = NewVecLiteralVarDecl(BRHSTy);
      VD->setInit(RHS);
      DeclVec.push_back(VD);

      // Make a DeclRefExpr
      SourceLocation loc;
      RHS = new (ASTCtx) DeclRefExpr(VD, BRHSTy, VK_RValue, loc);
    }
  }

  ExprVector LHSVec;
  MakeElementExprs(DeclVec, LHSVec, LHS);
  assert((LHSVec.size() > 0) && "Wrong element exprs");

  bool IsScalarRHS = RHS->getType()->isScalarType();
  if (LHSVec.size() == 1 && IsScalarRHS) {
    return NewBinaryOperator(LHSVec[0], Op, RHS);
  }

  Expr *NewExpr = 0;
  if (IsScalarRHS) {
    // scalar RHS
    for (unsigned i = 0, e = LHSVec.size(); i < e; i++) {
      Expr *OneExpr = NewBinaryOperator(LHSVec[i], Op, RHS);
      if (NewExpr) {
        NewExpr = NewBinaryOperator(NewExpr, BO_Comma, OneExpr);
      } else {
        NewExpr = OneExpr;
      }
    }
  } else if (CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(RHS)) {
    unsigned NumElems = LHSVec.size();
    Expr **Args = new (ASTCtx) Expr*[NumElems];
    TransformVectorLiteralExpr(CLE, Args, 0);

    for (unsigned i = 0; i < NumElems; i++) {
      Expr *OneExpr = NewBinaryOperator(LHSVec[i], Op, Args[i]);
      if (NewExpr) {
        NewExpr = NewBinaryOperator(NewExpr, BO_Comma, OneExpr);
      } else {
        NewExpr = OneExpr;
      }
    }
  } else if (ExtVectorElementExpr *EE = dyn_cast<ExtVectorElementExpr>(RHS)) {
    ExprVector RHSVec;
    MakeElementExprs(DeclVec, RHSVec, EE);
    assert((LHSVec.size() == RHSVec.size()) && "Different LHS and RHS?");

    for (unsigned i = 0, e = LHSVec.size(); i < e; i++) {
      Expr *OneExpr = NewBinaryOperator(LHSVec[i], Op, RHSVec[i]);
      if (NewExpr) {
        NewExpr = NewBinaryOperator(NewExpr, BO_Comma, OneExpr);
      } else {
        NewExpr = OneExpr;
      }
    }
  } else {
    // vector RHS
    for (unsigned i = 0, e = LHSVec.size(); i < e; i++) {
      QualType Ty = LHSVec[i]->getType();

      // RHS[i]
      ArraySubscriptExpr *ElemRHS = new (ASTCtx) ArraySubscriptExpr(
          RHS, 
          CLExprs.getExpr((CLExpressions::ExprKind)(CLExpressions::ZERO + i)), 
          Ty, VK_RValue, OK_Ordinary, SourceLocation());

      Expr *OneExpr = NewBinaryOperator(LHSVec[i], Op, ElemRHS);
      if (NewExpr) {
        NewExpr = NewBinaryOperator(NewExpr, BO_Comma, OneExpr);
      } else {
        NewExpr = OneExpr;
      }
    }
  }

  return NewExpr;
}
Пример #13
0
Expr *TransformVector::ConvertVecLiteralInExpr(DeclVector &DeclVec,
                                               Expr *E,
                                               bool IsTopDecl) {
  if (CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(E)) {
    QualType LitTy = CLE->getType();
    if (LitTy->isVectorType()) { // vector literal
      VecLiteralMode = true;
      Expr *Init = ConvertVecLiteralInExpr(DeclVec, CLE->getInitializer());
      CLE->setInitializer(Init);
      VecLiteralMode = false;

      // Make a VarDecl with an initialization expr.
      VarDecl *VD = NewVecLiteralVarDecl(LitTy);
      VD->setInit(CLE);
      DeclVec.push_back(VD);

      // Return a DeclRefExpr that refers above VarDecl.
      return new (ASTCtx) DeclRefExpr(VD, LitTy, VK_RValue, SourceLocation());
    } else {
      Expr *Init = ConvertVecLiteralInExpr(DeclVec, CLE->getInitializer());
      CLE->setInitializer(Init);
    }

    return CLE;
  }
  else if (ExtVectorElementExpr *EVEE = dyn_cast<ExtVectorElementExpr>(E)) {
    unsigned NumElems = EVEE->getNumElements();
    Expr *NewE = TransformExpr(E);

    if (IsTopDecl && NumElems > 1) {
      // vector literal
      VarDecl *VD = NewVecLiteralVarDecl(EVEE->getType());
      VD->setInit(NewE);
      DeclVec.push_back(VD);

      // Return a DeclRefExpr that refers above VarDecl.
      SourceLocation loc;
      return new (ASTCtx) DeclRefExpr(VD, VD->getType(), VK_RValue, loc);
    }
    return NewE;
  }
  else if (CompoundAssignOperator *CA = dyn_cast<CompoundAssignOperator>(E)) {
    Expr *CLHS = CA->getLHS();
    Expr *CRHS = CA->getRHS();

    if (ExtVectorElementExpr *LHS = dyn_cast<ExtVectorElementExpr>(CLHS)) {
      Expr *NewE = ConvertAssignExpr(DeclVec, LHS, CA->getOpcode(), CRHS);
      ASTCtx.Deallocate(CA);
      return NewE;
    } else {
      // LHS & RHS
      CA->setLHS(ConvertVecLiteralInExpr(DeclVec, CLHS));
      CA->setRHS(ConvertVecLiteralInExpr(DeclVec, CRHS));
      return CA;
    }
  }
  else if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(E)) {
    Expr *BLHS = BinOp->getLHS();
    Expr *BRHS = BinOp->getRHS();
    BinaryOperatorKind Op = BinOp->getOpcode();

    if (Op == BO_Assign) {
      if (ExtVectorElementExpr *LHS = dyn_cast<ExtVectorElementExpr>(BLHS)) {
        Expr *NewE = ConvertAssignExpr(DeclVec, LHS, Op, BRHS);
        ASTCtx.Deallocate(BinOp);
        return NewE;
      } 
    } 

    // LHS & RHS
    BinOp->setLHS(ConvertVecLiteralInExpr(DeclVec, BLHS));
    BinOp->setRHS(ConvertVecLiteralInExpr(DeclVec, BRHS));

    return BinOp;
  }
  else if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
    PE->setSubExpr(ConvertVecLiteralInExpr(DeclVec, PE->getSubExpr()));
    return PE;
  }
  else if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(E)) {
    UOp->setSubExpr(ConvertVecLiteralInExpr(DeclVec, UOp->getSubExpr()));
    return UOp;
  }
  else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
    ASE->setLHS(ConvertVecLiteralInExpr(DeclVec, ASE->getLHS()));
    ASE->setRHS(ConvertVecLiteralInExpr(DeclVec, ASE->getRHS()));
    return ASE;
  }
  else if (CallExpr *Call = dyn_cast<CallExpr>(E)) {
    for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
      Call->setArg(i, ConvertVecLiteralInExpr(DeclVec, Call->getArg(i)));
    }

    // If a vload function exists in a vector literal, it can be 
    // code-motioned in order to improve performance.
    if (VecLiteralMode) {
      Expr *Callee = Call->getCallee();
      if (CLUtils::IsVectorDataFunction(Callee) != -1) {
        QualType CallTy = Call->getType();
        VarDecl *VD = NewVecLiteralVarDecl(CallTy);
        VD->setInit(Call);
        DeclVec.push_back(VD);
        
        SourceLocation loc;
        return new (ASTCtx) DeclRefExpr(VD, CallTy, VK_RValue, loc);
      }
    }

    return Call;
  }
  else if (CStyleCastExpr *CSCE = dyn_cast<CStyleCastExpr>(E)) {
    CSCE->setSubExpr(ConvertVecLiteralInExpr(DeclVec, CSCE->getSubExpr()));
    return CSCE;
  }
  else if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
    ICE->setSubExpr(ConvertVecLiteralInExpr(DeclVec, ICE->getSubExpr()));
    return ICE;
  }
  else if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) {
    return TransformExpr(CO);
  }
  else if (InitListExpr *ILE = dyn_cast<InitListExpr>(E)) {
    for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i) {
      if (Expr *init = ILE->getInit(i)) {
        init = ConvertVecLiteralInExpr(DeclVec, init);
        ILE->setInit(i, init);
      }
    }
    return ILE;
  }
  else if (DesignatedInitExpr *DIE = dyn_cast<DesignatedInitExpr>(E)) {
    DIE->setInit(ConvertVecLiteralInExpr(DeclVec, DIE->getInit()));
    return DIE;
  }

  return E;
}
Пример #14
0
/// CheckStaticCast - Check that a static_cast\<DestType\>(SrcExpr) is valid.
/// Refer to C++ 5.2.9 for details. Static casts are mostly used for making
/// implicit conversions explicit and getting rid of data loss warnings.
void
CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                const SourceRange &OpRange)
{
  // The order the tests is not entirely arbitrary. There is one conversion
  // that can be handled in two different ways. Given:
  // struct A {};
  // struct B : public A {
  //   B(); B(const A&);
  // };
  // const A &a = B();
  // the cast static_cast<const B&>(a) could be seen as either a static
  // reference downcast, or an explicit invocation of the user-defined
  // conversion using B's conversion constructor.
  // DR 427 specifies that the downcast is to be applied here.

  // FIXME: With N2812, casts to rvalue refs will change.

  // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
  if (DestType->isVoidType()) {
    return;
  }

  // C++ 5.2.9p5, reference downcast.
  // See the function for details.
  // DR 427 specifies that this is to be applied before paragraph 2.
  if (TryStaticReferenceDowncast(Self, SrcExpr, DestType, OpRange)
      > TSC_NotApplicable) {
    return;
  }

  // N2844 5.2.9p3: An lvalue of type "cv1 T1" can be cast to type "rvalue
  //   reference to cv2 T2" if "cv2 T2" is reference-compatible with "cv1 T1".
  if (TryLValueToRValueCast(Self, SrcExpr, DestType, OpRange) >
      TSC_NotApplicable) {
    return;
  }

  // C++ 5.2.9p2: An expression e can be explicitly converted to a type T
  //   [...] if the declaration "T t(e);" is well-formed, [...].
  if (TryStaticImplicitCast(Self, SrcExpr, DestType, OpRange) >
      TSC_NotApplicable) {
    return;
  }

  // C++ 5.2.9p6: May apply the reverse of any standard conversion, except
  // lvalue-to-rvalue, array-to-pointer, function-to-pointer, and boolean
  // conversions, subject to further restrictions.
  // Also, C++ 5.2.9p1 forbids casting away constness, which makes reversal
  // of qualification conversions impossible.

  // The lvalue-to-rvalue, array-to-pointer and function-to-pointer conversions
  // are applied to the expression.
  QualType OrigSrcType = SrcExpr->getType();
  Self.DefaultFunctionArrayConversion(SrcExpr);

  QualType SrcType = Self.Context.getCanonicalType(SrcExpr->getType());

  // Reverse integral promotion/conversion. All such conversions are themselves
  // again integral promotions or conversions and are thus already handled by
  // p2 (TryDirectInitialization above).
  // (Note: any data loss warnings should be suppressed.)
  // The exception is the reverse of enum->integer, i.e. integer->enum (and
  // enum->enum). See also C++ 5.2.9p7.
  // The same goes for reverse floating point promotion/conversion and
  // floating-integral conversions. Again, only floating->enum is relevant.
  if (DestType->isEnumeralType()) {
    if (SrcType->isComplexType() || SrcType->isVectorType()) {
      // Fall through - these cannot be converted.
    } else if (SrcType->isArithmeticType() || SrcType->isEnumeralType()) {
      return;
    }
  }

  // Reverse pointer upcast. C++ 4.10p3 specifies pointer upcast.
  // C++ 5.2.9p8 additionally disallows a cast path through virtual inheritance.
  if (TryStaticPointerDowncast(Self, SrcType, DestType, OpRange)
      > TSC_NotApplicable) {
    return;
  }

  // Reverse member pointer conversion. C++ 4.11 specifies member pointer
  // conversion. C++ 5.2.9p9 has additional information.
  // DR54's access restrictions apply here also.
  if (TryStaticMemberPointerUpcast(Self, SrcType, DestType, OpRange)
      > TSC_NotApplicable) {
    return;
  }

  // Reverse pointer conversion to void*. C++ 4.10.p2 specifies conversion to
  // void*. C++ 5.2.9p10 specifies additional restrictions, which really is
  // just the usual constness stuff.
  if (const PointerType *SrcPointer = SrcType->getAsPointerType()) {
    QualType SrcPointee = SrcPointer->getPointeeType();
    if (SrcPointee->isVoidType()) {
      if (const PointerType *DestPointer = DestType->getAsPointerType()) {
        QualType DestPointee = DestPointer->getPointeeType();
        if (DestPointee->isIncompleteOrObjectType()) {
          // This is definitely the intended conversion, but it might fail due
          // to a const violation.
          if (!DestPointee.isAtLeastAsQualifiedAs(SrcPointee)) {
            Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_const_away)
              << "static_cast" << DestType << OrigSrcType << OpRange;
          }
          return;
        }
      }
    }
  }

  // We tried everything. Everything! Nothing works! :-(
  // FIXME: Error reporting could be a lot better. Should store the reason why
  // every substep failed and, at the end, select the most specific and report
  // that.
  Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_generic)
    << "static_cast" << DestType << OrigSrcType
    << OpRange;
}
Пример #15
0
// access image memory at given index
Expr *ASTTranslate::accessMemImgAt(DeclRefExpr *LHS, HipaccAccessor *Acc,
    MemoryAccess mem_acc, Expr *idx_x, Expr *idx_y) {
  Expr *result, *coord;

  // mark image as being used within the kernel
  Kernel->setUsed(LHS->getNameInfo().getAsString());

  // construct coordinate: (int2)(gid_x, gid_y)
  coord = createBinaryOperator(Ctx, idx_x, idx_y, BO_Comma, Ctx.IntTy);
  coord = createParenExpr(Ctx, coord);
  QualType QTcoord = simdTypes.getSIMDType(Ctx.IntTy, "int", SIMD2);
  coord = createCStyleCastExpr(Ctx, QTcoord, CK_VectorSplat, coord, nullptr,
      Ctx.getTrivialTypeSourceInfo(QTcoord));
  FunctionDecl *image_function = getImageFunction(Acc, mem_acc);

  // create function call for image objects in OpenCL
  if (mem_acc == READ_ONLY) {
    // parameters for read_image
    SmallVector<Expr *, 16> args;
    args.push_back(LHS);
    args.push_back(kernelSamplerRef);
    args.push_back(coord);

    result = createFunctionCall(Ctx, image_function, args);

    QualType QT = Acc->getImage()->getType();
    if (QT->isVectorType()) {
      SmallVector<Expr *, 16> args;
      args.push_back(result);
      result = createFunctionCall(Ctx, getConvertFunction(QT), args);
    } else {
      result = createExtVectorElementExpr(Ctx, QT, result, "x");
    }
  } else {
    QualType QT;

    // determine cast type for write_image functions
    if (image_function == builtins.getBuiltinFunction(OPENCLBIwrite_imagei)) {
      QT = simdTypes.getSIMDType(Ctx.IntTy, "int", SIMD4);
    } else if (image_function ==
        builtins.getBuiltinFunction(OPENCLBIwrite_imageui)) {
      QT = simdTypes.getSIMDType(Ctx.UnsignedIntTy, "uint", SIMD4);
    } else {
      QT = simdTypes.getSIMDType(Ctx.FloatTy, "float", SIMD4);
    }

    // writeImageRHS is set by VisitBinaryOperator - side effect
    if (!writeImageRHS->getType()->isVectorType()) {
      // introduce temporary for propagating the RHS to a vector
      std::string tmp_lit("_tmp" + std::to_string(literalCount++));
      VarDecl *tmp_decl = createVarDecl(Ctx, kernelDecl, tmp_lit, QT,
          writeImageRHS);
      DeclContext *DC = FunctionDecl::castToDeclContext(kernelDecl);
      DC->addDecl(tmp_decl);
      DeclRefExpr *tmp_dre = createDeclRefExpr(Ctx, tmp_decl);
      preStmts.push_back(createDeclStmt(Ctx, tmp_decl));
      preCStmt.push_back(curCStmt);
      writeImageRHS = tmp_dre;
    }

    if (writeImageRHS->getType() != QT) {
      // convert to proper vector type
      SmallVector<Expr *, 16> args;
      args.push_back(writeImageRHS);
      writeImageRHS = createFunctionCall(Ctx, getConvertFunction(QT), args);
    }

    // parameters for write_image
    SmallVector<Expr *, 16> args;
    args.push_back(LHS);
    args.push_back(coord);
    args.push_back(writeImageRHS);

    result = createFunctionCall(Ctx, image_function, args);
  }

  return result;
}
Пример #16
0
// get tex1Dfetch function for given Accessor
FunctionDecl *ASTTranslate::getTextureFunction(HipaccAccessor *Acc, MemoryAccess
    mem_acc) {
  QualType QT = Acc->getImage()->getType();
  bool isVecType = QT->isVectorType();

  if (isVecType) {
    QT = QT->getAs<VectorType>()->getElementType();
  }
  const BuiltinType *BT = QT->getAs<BuiltinType>();

  bool isOneDim = false, isLdg = false;
  switch (Kernel->useTextureMemory(Acc)) {
    default:                                 break;
    case Texture::Linear1D: isOneDim = true; break;
    case Texture::Ldg:      isLdg = true;    break;
  }

  switch (BT->getKind()) {
    case BuiltinType::WChar_U:
    case BuiltinType::WChar_S:
    case BuiltinType::ULongLong:
    case BuiltinType::UInt128:
    case BuiltinType::LongLong:
    case BuiltinType::Int128:
    case BuiltinType::LongDouble:
    case BuiltinType::Void:
    case BuiltinType::Bool:
    case BuiltinType::Long:
    case BuiltinType::ULong:
    case BuiltinType::Double:
    default:
      assert(0 && "BuiltinType for CUDA texture not supported.");

#define GET_BUILTIN_FUNCTION(TYPE) \
      (mem_acc == READ_ONLY ? \
          (isLdg ? \
              (isVecType ? builtins.getBuiltinFunction(CUDABI__ldg ## E4 ## TYPE) : \
                  builtins.getBuiltinFunction(CUDABI__ldg ## TYPE)) : \
              (isOneDim ? \
                  (isVecType ? builtins.getBuiltinFunction(CUDABItex1Dfetch ## E4 ## TYPE) : \
                      builtins.getBuiltinFunction(CUDABItex1Dfetch ## TYPE)) : \
                  (isVecType ? builtins.getBuiltinFunction(CUDABItex2D ## E4 ## TYPE) : \
                      builtins.getBuiltinFunction(CUDABItex2D ## TYPE)))) : \
          (isVecType ? builtins.getBuiltinFunction(CUDABIsurf2Dwrite ## E4 ## TYPE) : \
              builtins.getBuiltinFunction(CUDABIsurf2Dwrite ## TYPE)))

    case BuiltinType::Char_S:
    case BuiltinType::SChar:
      return GET_BUILTIN_FUNCTION(Sc);
    case BuiltinType::Char_U:
    case BuiltinType::UChar:
      return GET_BUILTIN_FUNCTION(Uc);
    case BuiltinType::Short:
      return GET_BUILTIN_FUNCTION(s);
    case BuiltinType::Char16:
    case BuiltinType::UShort:
      return GET_BUILTIN_FUNCTION(Us);
    case BuiltinType::Int:
      return GET_BUILTIN_FUNCTION(i);
    case BuiltinType::Char32:
    case BuiltinType::UInt:
      return GET_BUILTIN_FUNCTION(Ui);
    case BuiltinType::Float:
      return GET_BUILTIN_FUNCTION(f);
#undef GET_BUILTIN_FUNCTION
  }
}