29 AVRShiftExpand() : FunctionPass(ID) {}
33 StringRef getPassName()
const override {
return "AVR Shift Expansion"; }
36 void expand(BinaryOperator *BI);
41char AVRShiftExpand::ID = 0;
48bool AVRShiftExpand::runOnFunction(
Function &
F) {
50 auto &Ctx =
F.getContext();
55 if (
I.getType() == Type::getInt8Ty(Ctx) ||
56 I.getType() == Type::getInt16Ty(Ctx))
70 for (
auto *
I : ShiftInsts) {
75 return ShiftInsts.size() > 0;
78void AVRShiftExpand::expand(BinaryOperator *BI) {
82 Type *Int8Ty = Type::getInt8Ty(Ctx);
83 Value *Int8Zero = ConstantInt::get(Int8Ty, 0);
94 Builder.SetInsertPoint(&BB->
back());
99 Value *Cmp1 = Builder.CreateICmpEQ(ShiftAmount, Int8Zero);
100 Builder.CreateCondBr(Cmp1, EndBB, LoopBB);
104 Builder.SetInsertPoint(LoopBB);
105 PHINode *ShiftAmountPHI = Builder.CreatePHI(Int8Ty, 2);
107 PHINode *ValuePHI = Builder.CreatePHI(InputTy, 2);
112 Value *ShiftAmountSub =
113 Builder.CreateSub(ShiftAmountPHI, ConstantInt::get(Int8Ty, 1));
114 ShiftAmountPHI->
addIncoming(ShiftAmountSub, LoopBB);
121 case Instruction::Shl:
122 ValueShifted = Builder.CreateShl(ValuePHI, ConstantInt::get(InputTy, 1));
124 case Instruction::LShr:
125 ValueShifted = Builder.CreateLShr(ValuePHI, ConstantInt::get(InputTy, 1));
127 case Instruction::AShr:
128 ValueShifted = Builder.CreateAShr(ValuePHI, ConstantInt::get(InputTy, 1));
137 Value *Cmp2 = Builder.CreateICmpEQ(ShiftAmountSub, Int8Zero);
138 Builder.CreateCondBr(Cmp2, EndBB, LoopBB);
142 Builder.SetInsertPoint(BI);
143 PHINode *
Result = Builder.CreatePHI(InputTy, 2);
145 Result->addIncoming(ValueShifted, LoopBB);
Expand Atomic instructions
static bool runOnFunction(Function &F, bool PostInlining)
static Expected< BitVector > expand(StringRef S, StringRef Original)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const Function * getParent() const
Return the enclosing method, or null if none.
const Instruction & back() const
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
LLVM_ABI BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="", bool Before=false)
Split the basic block into two basic blocks at the specified instruction.
BinaryOps getOpcode() const
FunctionPass class - This class is used to implement most global optimizations.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
Pass interface - Implemented by all 'passes'.
void push_back(const T &Elt)
Value * getOperand(unsigned i) const
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
const ParentTy * getParent() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ BasicBlock
Various leaf nodes.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Pass * createAVRShiftExpandPass()
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.