/// dealing with icmps but allow any other integer that is <= 16 bits. Void
/// types are accepted so we can handle switches.
static bool isSupportedType(Value *V) {
- LLVM_DEBUG(dbgs() << "ARM CGP: isSupportedType: " << *V << "\n");
Type *Ty = V->getType();
// Allow voids and pointers, these won't be promoted.
Ty = cast<PointerType>(Ld->getPointerOperandType())->getElementType();
const IntegerType *IntTy = dyn_cast<IntegerType>(Ty);
- if (!IntTy) {
- LLVM_DEBUG(dbgs() << "ARM CGP: No, not an integer.\n");
+ if (!IntTy)
return false;
- }
return IntTy->getBitWidth() == ARMCodeGenPrepare::TypeSize;
}
static bool isSource(Value *V) {
if (!isa<IntegerType>(V->getType()))
return false;
- // TODO Allow truncs and zext to be sources.
+ // TODO Allow zext to be sources.
if (isa<Argument>(V))
return true;
else if (isa<LoadInst>(V))
return true;
else if (auto *Call = dyn_cast<CallInst>(V))
return Call->hasRetAttr(Attribute::AttrKind::ZExt);
+ else if (auto *Trunc = dyn_cast<TruncInst>(V))
+ return isSupportedType(Trunc);
return false;
}
}
static bool shouldPromote(Value *V) {
- if (!isa<IntegerType>(V->getType()) || isSink(V)) {
- LLVM_DEBUG(dbgs() << "ARM CGP: Don't need to promote: " << *V << "\n");
+ if (!isa<IntegerType>(V->getType()) || isSink(V))
return false;
- }
if (isSource(V))
return true;
Users.push_back(User);
}
- for (auto &U : Users)
+ for (auto *U : Users)
U->replaceUsesOfWith(From, To);
};
}
}
LLVM_DEBUG(dbgs() << "ARM CGP: Mutation complete:\n");
+ LLVM_DEBUG(dbgs();
+ for (auto *V : Sources)
+ V->dump();
+ for (auto *I : NewInsts)
+ I->dump();
+ for (auto *V : Visited) {
+ if (!Sources.count(V))
+ V->dump();
+ });
}
/// We accept most instructions, as well as Arguments and ConstantInsts. We
/// return value is zeroext. We don't allow opcodes that can introduce sign
/// bits.
bool ARMCodeGenPrepare::isSupportedValue(Value *V) {
- LLVM_DEBUG(dbgs() << "ARM CGP: Is " << *V << " supported?\n");
-
if (isa<ICmpInst>(V))
return true;
isa<LoadInst>(V))
return isSupportedType(V);
- if (isa<CastInst>(V) && !isa<SExtInst>(V))
+ // Truncs can be either sources or sinks.
+ if (auto *Trunc = dyn_cast<TruncInst>(V))
+ return isSupportedType(Trunc) || isSupportedType(Trunc->getOperand(0));
+
+ if (isa<CastInst>(V) && !isa<SExtInst>(V))
return isSupportedType(cast<CastInst>(V)->getOperand(0));
// Special cases for calls as we need to check for zeroext
return isSupportedType(Call) &&
Call->hasRetAttr(Attribute::AttrKind::ZExt);
- if (!isa<BinaryOperator>(V)) {
- LLVM_DEBUG(dbgs() << "ARM CGP: No, not a binary operator.\n");
+ if (!isa<BinaryOperator>(V))
return false;
- }
+
if (!isSupportedType(V))
return false;
// the tree has already been explored.
// TODO: This could limit the transform, ie if we try to promote something
// from an i8 and fail first, before trying an i16.
- if (AllVisited.count(V)) {
- LLVM_DEBUG(dbgs() << "ARM CGP: Already visited this: " << *V << "\n");
+ if (AllVisited.count(V))
return false;
- }
CurrentVisited.insert(V);
AllVisited.insert(V);
if (CI.isSigned() || !isa<IntegerType>(CI.getOperand(0)->getType()))
continue;
- LLVM_DEBUG(dbgs() << "ARM CGP: Searching from: " << CI << "\n");
for (auto &Op : CI.operands()) {
if (auto *I = dyn_cast<Instruction>(Op))
MadeChange |= TryToPromote(I);