本文整理汇总了C++中ConstantInt::getSExtValue方法的典型用法代码示例。如果您正苦于以下问题:C++ ConstantInt::getSExtValue方法的具体用法?C++ ConstantInt::getSExtValue怎么用?C++ ConstantInt::getSExtValue使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ConstantInt
的用法示例。
在下文中一共展示了ConstantInt::getSExtValue方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: newLeafBlock
// switchConvert - Convert the switch statement into a binary lookup of
// the case values. The function recursively builds this tree.
// LowerBound and UpperBound are used to keep track of the bounds for Val
// that have already been checked by a block emitted by one of the previous
// calls to switchConvert in the call stack.
BasicBlock *
LowerSwitch::switchConvert(CaseItr Begin, CaseItr End, ConstantInt *LowerBound,
ConstantInt *UpperBound, Value *Val,
BasicBlock *Predecessor, BasicBlock *OrigBlock,
BasicBlock *Default,
const std::vector<IntRange> &UnreachableRanges) {
unsigned Size = End - Begin;
if (Size == 1) {
// Check if the Case Range is perfectly squeezed in between
// already checked Upper and Lower bounds. If it is then we can avoid
// emitting the code that checks if the value actually falls in the range
// because the bounds already tell us so.
if (Begin->Low == LowerBound && Begin->High == UpperBound) {
unsigned NumMergedCases = 0;
if (LowerBound && UpperBound)
NumMergedCases =
UpperBound->getSExtValue() - LowerBound->getSExtValue();
fixPhis(Begin->BB, OrigBlock, Predecessor, NumMergedCases);
return Begin->BB;
}
return newLeafBlock(*Begin, Val, OrigBlock, Default);
}
unsigned Mid = Size / 2;
std::vector<CaseRange> LHS(Begin, Begin + Mid);
DEBUG(dbgs() << "LHS: " << LHS << "\n");
std::vector<CaseRange> RHS(Begin + Mid, End);
DEBUG(dbgs() << "RHS: " << RHS << "\n");
CaseRange &Pivot = *(Begin + Mid);
DEBUG(dbgs() << "Pivot ==> "
<< Pivot.Low->getValue()
<< " -" << Pivot.High->getValue() << "\n");
// NewLowerBound here should never be the integer minimal value.
// This is because it is computed from a case range that is never
// the smallest, so there is always a case range that has at least
// a smaller value.
ConstantInt *NewLowerBound = Pivot.Low;
// Because NewLowerBound is never the smallest representable integer
// it is safe here to subtract one.
ConstantInt *NewUpperBound = ConstantInt::get(NewLowerBound->getContext(),
NewLowerBound->getValue() - 1);
if (!UnreachableRanges.empty()) {
// Check if the gap between LHS's highest and NewLowerBound is unreachable.
int64_t GapLow = LHS.back().High->getSExtValue() + 1;
int64_t GapHigh = NewLowerBound->getSExtValue() - 1;
IntRange Gap = { GapLow, GapHigh };
if (GapHigh >= GapLow && IsInRanges(Gap, UnreachableRanges))
NewUpperBound = LHS.back().High;
}
DEBUG(dbgs() << "LHS Bounds ==> ";
if (LowerBound) {
dbgs() << LowerBound->getSExtValue();
} else {
dbgs() << "NONE";
}
dbgs() << " - " << NewUpperBound->getSExtValue() << "\n";
dbgs() << "RHS Bounds ==> ";
dbgs() << NewLowerBound->getSExtValue() << " - ";
if (UpperBound) {
dbgs() << UpperBound->getSExtValue() << "\n";
} else {
dbgs() << "NONE\n";
});
示例2: processTypeInfo
void ClassHierarchyUtils::processTypeInfo(GlobalVariable* TI, Module& M) {
if (find(classes.begin(), classes.end(), TI) == classes.end()) {
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Adding class " << TI->getName() << "\n");
classes.push_back(TI);
// First process the correspoding virtual table. We store the indexes of the primary
// and secondary vtables, indexed by the corresponding subobject offset. This will allow
// us to quickly jump to a particular sub-vtable.
if (typeInfoToVTable.find(TI) != typeInfoToVTable.end()) {
GlobalVariable* VT = typeInfoToVTable[TI];
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Found vtable: " << VT->getName() << "\n");
ConstantStruct* VTinit = cast<ConstantStruct>(VT->getInitializer());
for (int i=0; i<VTinit->getNumOperands(); i++) {
ConstantArray* VTinitElem = cast<ConstantArray>(VTinit->getOperand(i));
for (int j=0; j<VTinitElem->getNumOperands(); j++) {
// Each sub-vtable is preceded by a reference to the class's type_info instance.
// (See https://mentorembedded.github.io/cxx-abi/abi.html).
if (TI == VTinitElem->getOperand(j)->stripPointerCasts()) {
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Found TI at index " << i << "\n");
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Storing mapping " << VT->getName() << " <-> " << TI->getName() << "\n");
// the offset to top is the offset from the vptr pointing to this
// sub-vtable, back to the top of the object. This will be negative,
// but the absolute value gives us the offset from the start of the
// object (i.e. first vptr), to the subobject.
int offsetToTop = 0;
if (ConstantExpr* offsetValCast = dyn_cast<ConstantExpr>(VTinitElem->getOperand(j-1)->stripPointerCasts())) {
ConstantInt* offsetVal = cast<ConstantInt>(offsetValCast->getOperand(0));
offsetToTop = offsetVal->getSExtValue(); // will be 0 for the primary
}
if (offsetToTop > 0) {
report_fatal_error("ERROR: offsetToTop is positive!");
}
else {
offsetToTop *= -1;
}
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "offsetToTop: " << offsetToTop << "\n")
vTableToSecondaryVTableMaps[VT][offsetToTop] = pair<int, int>(i, j+1);
}
}
}
}
else {
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "No vtable found for " << TI->getName() << "\n");
}
// Now process the type_info struct, extract direct base class info (what
// their subobject offsets are, or if they are virtual then their
// virtual-base-offset-offset)
if (TI->hasInitializer()) {
ConstantStruct* TIinit = cast<ConstantStruct>(TI->getInitializer());
int TInumOperands = TIinit->getNumOperands();
if (TInumOperands > 2) { // first two operands are vptr and type name
// we have >= 1 base class(es).
if (TInumOperands == 3) {
// abi::__si_class_type_info: single, public, non-virtual base at
// offset 0
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "abi::__si_class_type_info\n");
GlobalVariable* baseTI = cast<GlobalVariable>(TIinit->getOperand(2)->stripPointerCasts());
classToSubclasses[baseTI].push_back(TI);
//dbgs() << " " << *baseTI << "\n";
classToBaseOffset[TI][baseTI] = 0;
processTypeInfo(baseTI, M);
}
else {
// abi::__vmi_class_type_info: all other cases
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "abi::__vmi_class_type_info\n");
// (skip over first two additional fields, which are "flags" and "base_count")
for (int i=4; i<TInumOperands; i+=2) {
GlobalVariable* baseTI = cast<GlobalVariable>(TIinit->getOperand(i)->stripPointerCasts());
classToSubclasses[baseTI].push_back(TI);
long offset_flags = cast<ConstantInt>(TIinit->getOperand(i+1))->getSExtValue();
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << TI->getName() << " -> " << baseTI->getName() << "\n");
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << " offset_flags = " << offset_flags << "\n");
ptrdiff_t offset = offset_flags >> offset_shift;
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << " offset = " << offset << "\n");
// If this a virtual base class, then we obtain the
// vbase-offset-offset. This is the offset from the start of the
// derived class's (primary) vtable to the location containing the
// vbase-offset, which is the offset from the start of the object
// to the virtual base's subobject. Note that virtual base
// subobjects only exist once and are laid out after all other
// non-virtual objects. We keep track of the vbase-offset-offset,
// so that we can find the vbase offset when going down the class
// hierarchy. (The vbase offset may differ every time but the
// vbase-offset-offset will remain the same relative to the current
// class's vtable in subclasses).
if (offset_flags & virtual_mask) { // is this a virtual base class?
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "virtual base class: " << baseTI->getName() << "\n");
int vbaseOffsetOffset = offset/sizeof(long); // this should be negative
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "vbase-offset-offset: " << vbaseOffsetOffset << "\n");
classToVBaseOffsetOffset[TI][baseTI] = vbaseOffsetOffset;
if (typeInfoToVTable.find(TI) != typeInfoToVTable.end()) {
GlobalVariable* VT = typeInfoToVTable[TI];
int vbaseOffsetIdx = vTableToSecondaryVTableMaps[VT][0].second+vbaseOffsetOffset;
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "vbase-offset-idx: " << vbaseOffsetIdx << "\n");
}
else {
//.........这里部分代码省略.........
示例3: getConsecutiveDirection
int InductionDescriptor::getConsecutiveDirection() const {
ConstantInt *ConstStep = getConstIntStepValue();
if (ConstStep && (ConstStep->isOne() || ConstStep->isMinusOne()))
return ConstStep->getSExtValue();
return 0;
}
示例4: isInductionPHI
bool InductionDescriptor::isInductionPHI(PHINode *Phi, const Loop *TheLoop,
ScalarEvolution *SE,
InductionDescriptor &D,
const SCEV *Expr) {
Type *PhiTy = Phi->getType();
// We only handle integer and pointer inductions variables.
if (!PhiTy->isIntegerTy() && !PhiTy->isPointerTy())
return false;
// Check that the PHI is consecutive.
const SCEV *PhiScev = Expr ? Expr : SE->getSCEV(Phi);
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(PhiScev);
if (!AR) {
DEBUG(dbgs() << "LV: PHI is not a poly recurrence.\n");
return false;
}
if (AR->getLoop() != TheLoop) {
// FIXME: We should treat this as a uniform. Unfortunately, we
// don't currently know how to handled uniform PHIs.
DEBUG(dbgs() << "LV: PHI is a recurrence with respect to an outer loop.\n");
return false;
}
Value *StartValue =
Phi->getIncomingValueForBlock(AR->getLoop()->getLoopPreheader());
const SCEV *Step = AR->getStepRecurrence(*SE);
// Calculate the pointer stride and check if it is consecutive.
// The stride may be a constant or a loop invariant integer value.
const SCEVConstant *ConstStep = dyn_cast<SCEVConstant>(Step);
if (!ConstStep && !SE->isLoopInvariant(Step, TheLoop))
return false;
if (PhiTy->isIntegerTy()) {
D = InductionDescriptor(StartValue, IK_IntInduction, Step);
return true;
}
assert(PhiTy->isPointerTy() && "The PHI must be a pointer");
// Pointer induction should be a constant.
if (!ConstStep)
return false;
ConstantInt *CV = ConstStep->getValue();
Type *PointerElementType = PhiTy->getPointerElementType();
// The pointer stride cannot be determined if the pointer element type is not
// sized.
if (!PointerElementType->isSized())
return false;
const DataLayout &DL = Phi->getModule()->getDataLayout();
int64_t Size = static_cast<int64_t>(DL.getTypeAllocSize(PointerElementType));
if (!Size)
return false;
int64_t CVSize = CV->getSExtValue();
if (CVSize % Size)
return false;
auto *StepValue = SE->getConstant(CV->getType(), CVSize / Size,
true /* signed */);
D = InductionDescriptor(StartValue, IK_PtrInduction, StepValue);
return true;
}
示例5: runOnModule
//.........这里部分代码省略.........
if (const ArrayType *XATy =
dyn_cast<ArrayType>(StrippedPtrTy->getElementType())){
// GEP (bitcast [10 x i8]* X to [0 x i8]*), i32 0, ... ?
if (CATy->getElementType() == XATy->getElementType()) {
// -> GEP [10 x i8]* X, i32 0, ...
// At this point, we know that the cast source type is a pointer
// to an array of the same type as the destination pointer
// array. Because the array type is never stepped over (there
// is a leading zero) we can fold the cast into this GEP.
GEP->setOperand(0, StrippedPtr);
continue;
}
}
}
} else if (GEP->getNumOperands() == 2) {
// Transform things like:
// %t = getelementptr i32* bitcast ([2 x i32]* %str to i32*), i32 %V
// into: %t1 = getelementptr [2 x i32]* %str, i32 0, i32 %V; bitcast
Type *SrcElTy = StrippedPtrTy->getElementType();
Type *ResElTy=cast<PointerType>(PtrOp->getType())->getElementType();
if (TD && SrcElTy->isArrayTy() &&
TD->getTypeAllocSize(cast<ArrayType>(SrcElTy)->getElementType()) ==
TD->getTypeAllocSize(ResElTy)) {
Value *Idx[2];
Idx[0] = Constant::getNullValue(Type::getInt32Ty(GEP->getContext()));
Idx[1] = GEP->getOperand(1);
Value *NewGEP = GetElementPtrInst::Create(nullptr, StrippedPtr, Idx,
GEP->getName(), GEP);
// V and GEP are both pointer types --> BitCast
GEP->replaceAllUsesWith(new BitCastInst(NewGEP, GEP->getType(), GEP->getName(), GEP));
continue;
}
// Transform things like:
// getelementptr i8* bitcast ([100 x double]* X to i8*), i32 %tmp
// (where tmp = 8*tmp2) into:
// getelementptr [100 x double]* %arr, i32 0, i32 %tmp2; bitcast
if (TD && SrcElTy->isArrayTy() && ResElTy->isIntegerTy(8)) {
uint64_t ArrayEltSize =
TD->getTypeAllocSize(cast<ArrayType>(SrcElTy)->getElementType());
// Check to see if "tmp" is a scale by a multiple of ArrayEltSize. We
// allow either a mul, shift, or constant here.
Value *NewIdx = 0;
ConstantInt *Scale = 0;
if (ArrayEltSize == 1) {
NewIdx = GEP->getOperand(1);
Scale = ConstantInt::get(cast<IntegerType>(NewIdx->getType()), 1);
} else if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(1))) {
NewIdx = ConstantInt::get(CI->getType(), 1);
Scale = CI;
} else if (Instruction *Inst =dyn_cast<Instruction>(GEP->getOperand(1))){
if (Inst->getOpcode() == Instruction::Shl &&
isa<ConstantInt>(Inst->getOperand(1))) {
ConstantInt *ShAmt = cast<ConstantInt>(Inst->getOperand(1));
uint32_t ShAmtVal = ShAmt->getLimitedValue(64);
Scale = ConstantInt::get(cast<IntegerType>(Inst->getType()),
1ULL << ShAmtVal);
NewIdx = Inst->getOperand(0);
} else if (Inst->getOpcode() == Instruction::Mul &&
isa<ConstantInt>(Inst->getOperand(1))) {
Scale = cast<ConstantInt>(Inst->getOperand(1));
NewIdx = Inst->getOperand(0);
}
}
// If the index will be to exactly the right offset with the scale taken
// out, perform the transformation. Note, we don't know whether Scale is
// signed or not. We'll use unsigned version of division/modulo
// operation after making sure Scale doesn't have the sign bit set.
if (ArrayEltSize && Scale && Scale->getSExtValue() >= 0LL &&
Scale->getZExtValue() % ArrayEltSize == 0) {
Scale = ConstantInt::get(Scale->getType(),
Scale->getZExtValue() / ArrayEltSize);
if (Scale->getZExtValue() != 1) {
Constant *C = ConstantExpr::getIntegerCast(Scale, NewIdx->getType(),
false /*ZExt*/);
NewIdx = BinaryOperator::Create(BinaryOperator::Mul, NewIdx, C, "idxscale");
}
// Insert the new GEP instruction.
Value *Idx[2];
Idx[0] = Constant::getNullValue(Type::getInt32Ty(GEP->getContext()));
Idx[1] = NewIdx;
Value *NewGEP = GetElementPtrInst::Create(nullptr, StrippedPtr, Idx,
GEP->getName(), GEP);
GEP->replaceAllUsesWith(new BitCastInst(NewGEP, GEP->getType(), GEP->getName(), GEP));
continue;
}
}
}
}
}
}
}
return true;
}
示例6: computeAddress
bool WebAssemblyFastISel::computeAddress(const Value *Obj, Address &Addr) {
const User *U = nullptr;
unsigned Opcode = Instruction::UserOp1;
if (const Instruction *I = dyn_cast<Instruction>(Obj)) {
// Don't walk into other basic blocks unless the object is an alloca from
// another block, otherwise it may not have a virtual register assigned.
if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(Obj)) ||
FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB) {
Opcode = I->getOpcode();
U = I;
}
} else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) {
Opcode = C->getOpcode();
U = C;
}
if (auto *Ty = dyn_cast<PointerType>(Obj->getType()))
if (Ty->getAddressSpace() > 255)
// Fast instruction selection doesn't support the special
// address spaces.
return false;
if (const GlobalValue *GV = dyn_cast<GlobalValue>(Obj)) {
if (Addr.getGlobalValue())
return false;
Addr.setGlobalValue(GV);
return true;
}
switch (Opcode) {
default:
break;
case Instruction::BitCast: {
// Look through bitcasts.
return computeAddress(U->getOperand(0), Addr);
}
case Instruction::IntToPtr: {
// Look past no-op inttoptrs.
if (TLI.getValueType(DL, U->getOperand(0)->getType()) ==
TLI.getPointerTy(DL))
return computeAddress(U->getOperand(0), Addr);
break;
}
case Instruction::PtrToInt: {
// Look past no-op ptrtoints.
if (TLI.getValueType(DL, U->getType()) == TLI.getPointerTy(DL))
return computeAddress(U->getOperand(0), Addr);
break;
}
case Instruction::GetElementPtr: {
Address SavedAddr = Addr;
uint64_t TmpOffset = Addr.getOffset();
// Iterate through the GEP folding the constants into offsets where
// we can.
for (gep_type_iterator GTI = gep_type_begin(U), E = gep_type_end(U);
GTI != E; ++GTI) {
const Value *Op = GTI.getOperand();
if (StructType *STy = dyn_cast<StructType>(*GTI)) {
const StructLayout *SL = DL.getStructLayout(STy);
unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();
TmpOffset += SL->getElementOffset(Idx);
} else {
uint64_t S = DL.getTypeAllocSize(GTI.getIndexedType());
for (;;) {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
// Constant-offset addressing.
TmpOffset += CI->getSExtValue() * S;
break;
}
if (S == 1 && Addr.isRegBase() && Addr.getReg() == 0) {
// An unscaled add of a register. Set it as the new base.
Addr.setReg(getRegForValue(Op));
break;
}
if (canFoldAddIntoGEP(U, Op)) {
// A compatible add with a constant operand. Fold the constant.
ConstantInt *CI =
cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1));
TmpOffset += CI->getSExtValue() * S;
// Iterate on the other operand.
Op = cast<AddOperator>(Op)->getOperand(0);
continue;
}
// Unsupported
goto unsupported_gep;
}
}
}
// Try to grab the base operand now.
Addr.setOffset(TmpOffset);
if (computeAddress(U->getOperand(0), Addr))
return true;
// We failed, restore everything and try the other options.
Addr = SavedAddr;
unsupported_gep:
break;
}
case Instruction::Alloca: {
const AllocaInst *AI = cast<AllocaInst>(Obj);
//.........这里部分代码省略.........
示例7: insertTripCount
//.........这里部分代码省略.........
++SICount[0];
}
Instruction* SI0 = dyn_cast<Instruction>(SI->getOperand(0));
if(L->contains(SI) && SI0 && SI0->getOpcode() == Instruction::Add){
next = SI0;
++SICount[1];
}
}
Assert(SICount[0]==1 && SICount[1]==1, "");
ind = IndOrNext;
}else{
if(isa<PHINode>(IndOrNext)){
PHINode* PHI = cast<PHINode>(IndOrNext);
ind = IndOrNext;
if(castoff(PHI->getIncomingValue(0)) == castoff(PHI->getIncomingValue(1)) && PHI->getParent() != H)
ind = castoff(PHI->getIncomingValue(0));
addfirst = false;
}else if(IndOrNext->getOpcode() == Instruction::Add){
next = IndOrNext;
addfirst = true;
}else{
Assert(0 ,"unknow how to analysis");
}
for(auto I = H->begin();isa<PHINode>(I);++I){
PHINode* P = cast<PHINode>(I);
if(ind && P == ind){
//start = P->getIncomingValueForBlock(L->getLoopPredecessor());
start = tryFindStart(P, L, startBB);
next = dyn_cast<Instruction>(P->getIncomingValueForBlock(L->getLoopLatch()));
}else if(next && P->getIncomingValueForBlock(L->getLoopLatch()) == next){
//start = P->getIncomingValueForBlock(L->getLoopPredecessor());
start = tryFindStart(P, L, startBB);
ind = P;
}
}
}
Assert(start ,"couldn't find a start value");
//process complex loops later
//DEBUG(if(L->getLoopDepth()>1 || !L->getSubLoops().empty()) return NULL);
DEBUG(errs()<<"start value:"<<*start<<"\n");
DEBUG(errs()<<"ind value:"<<*ind<<"\n");
DEBUG(errs()<<"next value:"<<*next<<"\n");
//process non add later
unsigned next_phi_idx = 0;
ConstantInt* Step = NULL,*PrevStep = NULL;/*only used if next is phi node*/
ret_null_fail(next, "");
PHINode* next_phi = dyn_cast<PHINode>(next);
do{
if(next_phi) {
next = dyn_cast<Instruction>(next_phi->getIncomingValue(next_phi_idx));
ret_null_fail(next, "");
DEBUG(errs()<<"next phi "<<next_phi_idx<<":"<<*next<<"\n");
if(Step&&PrevStep){
Assert(Step->getSExtValue() == PrevStep->getSExtValue(),"");
}
PrevStep = Step;
}
Assert(next->getOpcode() == Instruction::Add , "why induction increment is not Add");
Assert(next->getOperand(0) == ind ,"why induction increment is not add it self");
Step = dyn_cast<ConstantInt>(next->getOperand(1));
Assert(Step,"");
}while(next_phi && ++next_phi_idx<next_phi->getNumIncomingValues());
//RET_ON_FAIL(Step->equalsInt(1));
//assert(VERBOSE(Step->equalsInt(1),Step) && "why induction increment number is not 1");
Value* RES = NULL;
//if there are no predecessor, we can insert code into start value basicblock
IRBuilder<> Builder(InsertPos);
Assert(start->getType()->isIntegerTy() && END->getType()->isIntegerTy() , " why increment is not integer type");
if(start->getType() != END->getType()){
start = Builder.CreateCast(CastInst::getCastOpcode(start, false,
END->getType(), false),start,END->getType());
}
if(Step->getType() != END->getType()){
//Because Step is a Constant, so it casted is constant
Step = dyn_cast<ConstantInt>(Builder.CreateCast(CastInst::getCastOpcode(Step, false,
END->getType(), false),Step,END->getType()));
AssertRuntime(Step);
}
if(Step->isMinusOne())
RES = Builder.CreateSub(start,END);
else//Step Couldn't be zero
RES = Builder.CreateSub(END, start);
if(addfirst) OneStep -= 1;
if(Step->isMinusOne()) OneStep*=-1;
assert(OneStep<=1 && OneStep>=-1);
RES = (OneStep==1)?Builder.CreateAdd(RES,Step):(OneStep==-1)?Builder.CreateSub(RES, Step):RES;
if(!Step->isMinusOne()&&!Step->isOne())
RES = Builder.CreateSDiv(RES, Step);
RES->setName(H->getName()+".tc");
return RES;
}
示例8: runOnFunction
bool HexagonOptimizeSZextends::runOnFunction(Function &F) {
unsigned Idx = 1;
// Try to optimize sign extends in formal parameters. It's relying on
// callee already sign extending the values. I'm not sure if our ABI
// requires callee to sign extend though.
for (auto &Arg : F.args()) {
if (F.getAttributes().hasAttribute(Idx, Attribute::SExt)) {
if (!isa<PointerType>(Arg.getType())) {
for (auto UI = Arg.use_begin(); UI != Arg.use_end();) {
if (isa<SExtInst>(*UI)) {
Instruction* Use = cast<Instruction>(*UI);
SExtInst* SI = new SExtInst(&Arg, Use->getType());
assert (EVT::getEVT(SI->getType()) ==
(EVT::getEVT(Use->getType())));
++UI;
Use->replaceAllUsesWith(SI);
Instruction* First = &F.getEntryBlock().front();
SI->insertBefore(First);
Use->eraseFromParent();
} else {
++UI;
}
}
}
}
++Idx;
}
// Try to remove redundant sext operations on Hexagon. The hardware
// already sign extends many 16 bit intrinsic operations to 32 bits.
// For example:
// %34 = tail call i32 @llvm.hexagon.A2.addh.l16.sat.ll(i32 %x, i32 %y)
// %sext233 = shl i32 %34, 16
// %conv52 = ashr exact i32 %sext233, 16
for (auto &B : F) {
for (auto &I : B) {
// Look for arithmetic shift right by 16.
BinaryOperator *Ashr = dyn_cast<BinaryOperator>(&I);
if (!(Ashr && Ashr->getOpcode() == Instruction::AShr))
continue;
Value *AshrOp1 = Ashr->getOperand(1);
ConstantInt *C = dyn_cast<ConstantInt>(AshrOp1);
// Right shifted by 16.
if (!(C && C->getSExtValue() == 16))
continue;
// The first operand of Ashr comes from logical shift left.
Instruction *Shl = dyn_cast<Instruction>(Ashr->getOperand(0));
if (!(Shl && Shl->getOpcode() == Instruction::Shl))
continue;
Value *Intr = Shl->getOperand(0);
Value *ShlOp1 = Shl->getOperand(1);
C = dyn_cast<ConstantInt>(ShlOp1);
// Left shifted by 16.
if (!(C && C->getSExtValue() == 16))
continue;
// The first operand of Shl comes from an intrinsic.
if (IntrinsicInst *I = dyn_cast<IntrinsicInst>(Intr)) {
if (!intrinsicAlreadySextended(I->getIntrinsicID()))
continue;
// All is well. Replace all uses of AShr with I.
for (auto UI = Ashr->user_begin(), UE = Ashr->user_end();
UI != UE; ++UI) {
const Use &TheUse = UI.getUse();
if (Instruction *J = dyn_cast<Instruction>(TheUse.getUser())) {
J->replaceUsesOfWith(Ashr, I);
}
}
}
}
}
return true;
}
示例9: constructGraph
void CGGraph::constructGraph() {
std::vector<CGConstraint*>::iterator it;
std::string nodeName;
CGConstraint* curConstraint;
CGNode* firstNode;
CGNode* secondNode;
std::vector<int>::iterator lengthIt;
int curValue;
ConstantInt* cInt;
for (it = constraints.begin(); it != constraints.end(); ++it) {
curConstraint = *it;
Instruction* PP = curConstraint->programPoint;
switch(curConstraint->type) {
case CGConstraint::C1:
{
firstNode = getNode(getNameFromValue(curConstraint->programPoint->getOperand(0), PP));
secondNode = getNode(getNameFromValue(curConstraint->programPoint->getOperand(1), PP));
firstNode->connectTo(secondNode, 0);
break;
}
case CGConstraint::C2:
{
if (isa<StoreInst>(PP)) {
/*
operand(0) = constant int or variable of int type
operand(1) = var being stored into
*/
firstNode = getNode(getNameFromValue(PP->getOperand(0), PP));
secondNode = getNode(getNameFromValue(PP->getOperand(1), PP));
firstNode->connectTo(secondNode, 0);
}
else if (isa<LoadInst>(PP)) {
/*
operand(0) = pointer being loaded from
(Value*)PP = var being loaded into
*/
firstNode = getNode(getNameFromValue(PP->getOperand(0), PP));
secondNode = getNode(getNameFromValue(PP, PP));
firstNode->connectTo(secondNode, 0);
}
else if (isa<CastInst>(PP)) {
/*
operand(0) = var being casted
(Value*)PP = var getting the result of the cast
*/
firstNode = getNode(getNameFromValue(PP->getOperand(0), PP));
secondNode = getNode(getNameFromValue(PP, PP));
firstNode->connectTo(secondNode, 0);
}
break;
}
case CGConstraint::C3:
{
secondNode = getNode(getNameFromValue(PP, PP));
if ((cInt = dyn_cast<ConstantInt>(curConstraint->programPoint->getOperand(0)))) {
firstNode = getNode(getNameFromValue(curConstraint->programPoint->getOperand(1), PP));
} else if ((cInt = dyn_cast<ConstantInt>(curConstraint->programPoint->getOperand(1)))) {
firstNode = getNode(getNameFromValue(curConstraint->programPoint->getOperand(0), PP));
} else {
return;
}
curValue = cInt->getSExtValue();
firstNode->connectTo(secondNode, curValue);
break;
}
case CGConstraint::C4:
{
CmpInst* cmpInst;
BranchInst* branchInst;
if( !(branchInst = dyn_cast<BranchInst>(curConstraint->programPoint)) ) {
errs() << "ERROR: BranchInst cast unsuccessful for C4 in CGGraph::constructGraph() \n";
return;
}
if( !(cmpInst = dyn_cast<CmpInst>(owner->branchToCompare[branchInst])) ) {
errs() << "ERROR: CmpInst not found for C4 in CGGraph::constructGraph() \n";
return;
}
int size1, size2;
size1 = curConstraint->piAssignments.size();
size2 = curConstraint->piAssignments2.size();
/*
There are two possibilities here: (a) size1 = size2 = 2, or (b) size1 = size2 = 1;
If (b), there will be one operand in the compare inst that is a literal value.
That literal value still generates a constraint although it does not generate a pi assignment.
We need to account for that.
*/
if (size1 != size2) {
//.........这里部分代码省略.........
示例10: MatchOperationAddr
/// MatchOperationAddr - Given an instruction or constant expr, see if we can
/// fold the operation into the addressing mode. If so, update the addressing
/// mode and return true, otherwise return false without modifying AddrMode.
bool AddressingModeMatcher::MatchOperationAddr(User *AddrInst, unsigned Opcode,
unsigned Depth) {
// Avoid exponential behavior on extremely deep expression trees.
if (Depth >= 5) return false;
switch (Opcode) {
case Instruction::PtrToInt:
// PtrToInt is always a noop, as we know that the int type is pointer sized.
return MatchAddr(AddrInst->getOperand(0), Depth);
case Instruction::IntToPtr:
// This inttoptr is a no-op if the integer type is pointer sized.
if (TLI.getValueType(AddrInst->getOperand(0)->getType()) ==
TLI.getPointerTy())
return MatchAddr(AddrInst->getOperand(0), Depth);
return false;
case Instruction::BitCast:
// BitCast is always a noop, and we can handle it as long as it is
// int->int or pointer->pointer (we don't want int<->fp or something).
if ((AddrInst->getOperand(0)->getType()->isPointerTy() ||
AddrInst->getOperand(0)->getType()->isIntegerTy()) &&
// Don't touch identity bitcasts. These were probably put here by LSR,
// and we don't want to mess around with them. Assume it knows what it
// is doing.
AddrInst->getOperand(0)->getType() != AddrInst->getType())
return MatchAddr(AddrInst->getOperand(0), Depth);
return false;
case Instruction::Add: {
// Check to see if we can merge in the RHS then the LHS. If so, we win.
ExtAddrMode BackupAddrMode = AddrMode;
unsigned OldSize = AddrModeInsts.size();
if (MatchAddr(AddrInst->getOperand(1), Depth+1) &&
MatchAddr(AddrInst->getOperand(0), Depth+1))
return true;
// Restore the old addr mode info.
AddrMode = BackupAddrMode;
AddrModeInsts.resize(OldSize);
// Otherwise this was over-aggressive. Try merging in the LHS then the RHS.
if (MatchAddr(AddrInst->getOperand(0), Depth+1) &&
MatchAddr(AddrInst->getOperand(1), Depth+1))
return true;
// Otherwise we definitely can't merge the ADD in.
AddrMode = BackupAddrMode;
AddrModeInsts.resize(OldSize);
break;
}
//case Instruction::Or:
// TODO: We can handle "Or Val, Imm" iff this OR is equivalent to an ADD.
//break;
case Instruction::Mul:
case Instruction::Shl: {
// Can only handle X*C and X << C.
ConstantInt *RHS = dyn_cast<ConstantInt>(AddrInst->getOperand(1));
if (!RHS) return false;
int64_t Scale = RHS->getSExtValue();
if (Opcode == Instruction::Shl)
Scale = 1LL << Scale;
return MatchScaledValue(AddrInst->getOperand(0), Scale, Depth);
}
case Instruction::GetElementPtr: {
// Scan the GEP. We check it if it contains constant offsets and at most
// one variable offset.
int VariableOperand = -1;
unsigned VariableScale = 0;
int64_t ConstantOffset = 0;
const TargetData *TD = TLI.getTargetData();
gep_type_iterator GTI = gep_type_begin(AddrInst);
for (unsigned i = 1, e = AddrInst->getNumOperands(); i != e; ++i, ++GTI) {
if (const StructType *STy = dyn_cast<StructType>(*GTI)) {
const StructLayout *SL = TD->getStructLayout(STy);
unsigned Idx =
cast<ConstantInt>(AddrInst->getOperand(i))->getZExtValue();
ConstantOffset += SL->getElementOffset(Idx);
} else {
uint64_t TypeSize = TD->getTypeAllocSize(GTI.getIndexedType());
if (ConstantInt *CI = dyn_cast<ConstantInt>(AddrInst->getOperand(i))) {
ConstantOffset += CI->getSExtValue()*TypeSize;
} else if (TypeSize) { // Scales of zero don't do anything.
// We only allow one variable index at the moment.
if (VariableOperand != -1)
return false;
// Remember the variable index.
VariableOperand = i;
VariableScale = TypeSize;
}
}
}
// A common case is for the GEP to only do a constant offset. In this case,
// just add it to the disp field and check validity.
if (VariableOperand == -1) {
AddrMode.BaseOffs += ConstantOffset;
//.........这里部分代码省略.........
示例11: addVariableSourceDbgValue
void DebugDatabase::addVariableSourceDbgValue(DebugValue *dbgVal,
TraceScheduler *traceScheduler) {
DbgValueInst *dbgValInst = dbgVal->getDbgValInsn();
assert(dbgValInst);
int id = addVariableSource(dbgVal->getVariable(), dbgValInst, true);
std::string query;
if (dbgVal->isConstantInt()) {
// Get the integer value
ConstantInt *ci = cast<ConstantInt>(dbgValInst->getValue());
query = "INSERT INTO VariableSourceConstantInt ";
query += "(VariableSourceId, constantInt) ";
query += "VALUES (" + std::to_string(id);
query += "," + std::to_string(ci->getSExtValue());
query += ");";
runQuery(query);
} else if (dbgVal->isConstantNull()) {
query = "INSERT INTO VariableSourceConstantInt ";
query += "(VariableSourceId, constantInt) ";
query += "VALUES (" + std::to_string(id);
query += ",NULL";
query += ");";
runQuery(query);
} else if (dbgVal->isConstantPointer()) {
ConstantExpr *CE = dyn_cast<ConstantExpr>(dbgValInst->getValue());
assert(CE);
Value *base;
int offset;
getGEPBaseAndOffset(CE, &base, &offset);
int ramId = ramToIds[dbgInfo->getAlloc()->getRAM(base)];
assert(ramId);
query = "INSERT INTO VariableSourcePointer ";
query += "(VariableSourceId, ramId, offset) ";
query += "VALUES (" + std::to_string(id);
query += "," + std::to_string(ramId);
query += "," + std::to_string(offset);
query += ");";
runQuery(query);
} else if (dbgVal->isAlloca()) {
RAM *ram =
dbgInfo->getAlloc()->getRAM(dbgVal->getDbgValInsn()->getValue());
assert(ram);
int offset = dbgVal->getDbgValInsn()->getOffset();
int ramId = ramToIds[ram];
assert(ramId);
query = "INSERT INTO VariableSourcePointer ";
query += "(VariableSourceId, ramId, offset) ";
query += "VALUES (" + std::to_string(id);
query += "," + std::to_string(ramId);
query += "," + std::to_string(offset);
query += ");";
runQuery(query);
// dbgs() << *(dbgVal->getDbgValInsn()) << " is an alloca\n";
} else if (dbgVal->isArgument() || dbgVal->isFunctionCall() ||
dbgVal->isRegister()) {
GenerateRTL *hw = dbgVal->getVariable()->getGenRtl();
string signalName = dbgVal->getSignalName();
RTLSignal *signal;
signal = hw->getRTL()->findExists(signalName);
if (!signal) {
dbgs() << *(dbgVal->getDbgValInsn()) << "\n";
dbgs() << "Can't find signal " << dbgVal->getSignalName() << "\n";
}
// RTLSignal *signal =
// hw->getRTL()->find(dbgVal->getSignalName());
query = "INSERT INTO VariableSourceSignal ";
query += "(VariableSourceId, rtlSignalId) ";
query += "VALUES (" + std::to_string(id);
query += "," + std::to_string(rtlSignalToIds[signal]);
query += ");";
runQuery(query);
} else if (dbgVal->isUndefined()) {
query = "INSERT INTO VariableSourceUndefined ";
query += "(VariableSourceId) ";
query += "VALUES (" + std::to_string(id);
query += ");";
runQuery(query);
} else {
dbgs() << *(dbgValInst) << "\n";
dbgs() << *(dbgValInst->getValue()) << "\n";
assert(false);
}
//.........这里部分代码省略.........