/*! TODO: */ MHIModule::MHIModule() :Module(MODULE_NAME, MODULE_DISPLAY_NAME, MHIMODULE_VERSION), mParamUnits(PARAMETER_NAME_UNITS, Variable::eVariableTypeString, "Duration units", "Units are either seconds or frames", false), mParamDuration(PARAMETER_NAME_DURATION, Variable::eVariableTypeDouble, "Duration", "Duration parameter for MHI, in seconds or in frames", true) { mShortDescription = "Module for computing motion history image"; mLongDescription = "This module computes a motion history image from binary images"; ValueSet lUnitsValues; lUnitsValues.insert(Value("frames", "Frames", "Elapsed time is counted in frames")); lUnitsValues.insert(Value("seconds", "Seconds", "Elapsed time is counted in seconds")); mParamUnits.setPossibleValues(lUnitsValues); mParamUnits.setValueStr("frames"); mParamDuration.setValue(100); mParamDuration.setMinValue("0"); mParamDuration.setMaxValue("10000"); newParameter(mParamUnits); newParameter(mParamDuration); mInputSlotMask = newSlot(new ModuleSlot(this, INPUT_SLOT_NAME_MASK, INPUT_SLOT_DISPLAYNAME_MASK, "Input mask image used to compute MHI")); mOutputSlotMHI = newSlot(new ModuleSlot(this, OUTPUT_SLOT_NAME_MHI, OUTPUT_SLOT_DISPLAYNAME_MHI, "Output MHI image (floating point)", &mOutputMHI)); mOutputSlotMHIGray = newSlot(new ModuleSlot(this, OUTPUT_SLOT_NAME_MHI_GRAY, OUTPUT_SLOT_DISPLAYNAME_MHI_GRAY, "Output MHI image (gray scale image)", &mOutputMHIGray)); mOutputMHIIpl = NULL; mOutputMHIGrayIpl = NULL; mOutputMHI = NULL; mOutputMHIGray = NULL; mEllapsedTime = 0; }
PointerAnalysis::ValueSet PointerAnalysis::merge(PointerAnalysis::ValueSet a, PointerAnalysis::ValueSet b) { ValueSet r; for (auto i : a) r.insert(i); for (auto i : b) r.insert(i); return r; }
void FPInferredTargetsAnalysis::findAllFunctionPointersInValue(Value* V, ValueContextPairList& worklist, ValueSet& visited) { if (!visited.count(V)) { visited.insert(V); if (GlobalVariable* G = dyn_cast<GlobalVariable>(V)) { SDEBUG("soaap.analysis.infoflow.fp.infer", 3, dbgs() << INDENT_1 << "Global var: " << G->getName() << "\n"); // don't look in the llvm.global.annotations array if (G->getName() != "llvm.global.annotations" && G->hasInitializer()) { findAllFunctionPointersInValue(G->getInitializer(), worklist, visited); } } else if (ConstantArray* CA = dyn_cast<ConstantArray>(V)) { SDEBUG("soaap.analysis.infoflow.fp.infer", 3, dbgs() << INDENT_1 << "Constant array, num of operands: " << CA->getNumOperands() << "\n"); for (int i=0; i<CA->getNumOperands(); i++) { Value* V2 = CA->getOperand(i)->stripInBoundsOffsets(); findAllFunctionPointersInValue(V2, worklist, visited); } } else if (Function* F = dyn_cast<Function>(V)) { fpTargetsUniv.insert(F); SDEBUG("soaap.analysis.infoflow.fp.infer", 3, dbgs() << INDENT_1 << "Func: " << F->getName() << "\n"); setBitVector(state[ContextUtils::NO_CONTEXT][V], F); addToWorklist(V, ContextUtils::NO_CONTEXT, worklist); } else if (ConstantStruct* S = dyn_cast<ConstantStruct>(V)) { SDEBUG("soaap.analysis.infoflow.fp.infer", 3, dbgs() << INDENT_1 << "Struct, num of fields: " << S->getNumOperands() << "\n"); for (int j=0; j<S->getNumOperands(); j++) { Value* V2 = S->getOperand(j)->stripInBoundsOffsets(); findAllFunctionPointersInValue(V2, worklist, visited); } } } }
PointerAnalysis::ValueSet PointerAnalysis::join(PointerAnalysis::ValueSet a, PointerAnalysis::ValueSet b) { ValueSet r; for (auto i : a) if (b.count(i)) r.insert(i); return r; }
/*! TODO: */ TranslucencyModule::TranslucencyModule() :Module(MODULE_NAME, MODULE_DISPLAY_NAME, TRANSLUCENCYMODULE_VERSION), mParamMode(PARAMETER_NAME_MODE, Variable::eVariableTypeString, "Translucency mode", "The type of translucency to perform", false), mParamAlpha(PARAMETER_NAME_ALPHA, Variable::eVariableTypeDouble, "Translucency alpha", "Percentage of translucency (0=opaque, 1=invisible)", true), mParamInvert(PARAMETER_NAME_INVERT, Variable::eVariableTypeBool, "Invert mask", "Invert plain or alpha mask", true) { mShortDescription = "Module for embedding a color image in another one with translucency effect"; mLongDescription = "This module embeds an image into another one using an alpha mask (translucency)"; ValueSet lModeName; lModeName.insert(Value("image", "Whole Image", "Whole image is made translucent using the specified alpha value")); lModeName.insert(Value("plainmask", "Plain Mask", "Only the image pixels where the provided mask is non zero are made translucent using the specified alpha value")); lModeName.insert(Value("alphamask", "Alpha Mask", "Each pixel of the mask specify the alpha value to apply to the corresponding image pixel")); mParamMode.setPossibleValues(lModeName); NameSet lDependentParameterSet; lDependentParameterSet.insert(PARAMETER_NAME_ALPHA); lDependentParameterSet.insert(PARAMETER_NAME_INVERT); mParamMode.setDependentParameterNameSet(lDependentParameterSet); mParamMode.setValueStr("plainmask"); mParamAlpha.setValue(0.5); mParamAlpha.setMinValue("0"); mParamAlpha.setMaxValue("1"); mParamInvert.setValue(false); newParameter(mParamMode); newParameter(mParamAlpha); newParameter(mParamInvert); mInputSlotBackgroundColorImage = newSlot(new ModuleSlot(this, INPUT_SLOT_NAME_BGIMAGE, INPUT_SLOT_DISPLAYNAME_BGIMAGE, "Background image on which embedding with be performed")); mInputSlotTranslucencyColorImage = newSlot(new ModuleSlot(this, INPUT_SLOT_NAME_TRANSIMAGE, INPUT_SLOT_DISPLAYNAME_TRANSIMAGE, "Image that is going to be made translucent")); mInputSlotTranslucencyMaskImage = newSlot(new ModuleSlot(this, INPUT_SLOT_NAME_ALPHAMASK, INPUT_SLOT_DISPLAYNAME_ALPHAMASK, "Alpha mask used to make translucent image")); mOutputSlot = newSlot(new ModuleSlot(this, OUTPUT_SLOT_NAME_IMAGE, OUTPUT_SLOT_DISPLAYNAME_IMAGE, "Output image", &mOutputFrame)); mOutputFrameIpl = NULL; mOutputFrame = NULL; mTmpFrame1 = NULL; mTmpFrame2 = NULL; mTmpFrame3 = NULL; mTmpFrame4 = NULL; mTmpFrame5 = NULL; }
void CodeExtractor::findInputsOutputs(ValueSet &Inputs, ValueSet &Outputs) const { for (BasicBlock *BB : Blocks) { // If a used value is defined outside the region, it's an input. If an // instruction is used outside the region, it's an output. for (Instruction &II : *BB) { for (User::op_iterator OI = II.op_begin(), OE = II.op_end(); OI != OE; ++OI) if (definedInCaller(Blocks, *OI)) Inputs.insert(*OI); for (User *U : II.users()) if (!definedInRegion(Blocks, U)) { Outputs.insert(&II); break; } } } }
void Preparer::replaceUndefsWithNull(User *I, ValueSet &Replaced) { if (Replaced.count(I)) return; Replaced.insert(I); for (User::op_iterator OI = I->op_begin(); OI != I->op_end(); ++OI) { Value *V = OI->get(); if (isa<UndefValue>(V) && V->getType()->isPointerTy()) { OI->set(ConstantPointerNull::get(cast<PointerType>(V->getType()))); } if (User *I2 = dyn_cast<User>(V)) { replaceUndefsWithNull(I2, Replaced); } } }
void CodeExtractor::findAllocas(ValueSet &SinkCands, ValueSet &HoistCands, BasicBlock *&ExitBlock) const { Function *Func = (*Blocks.begin())->getParent(); ExitBlock = getCommonExitBlock(Blocks); for (BasicBlock &BB : *Func) { if (Blocks.count(&BB)) continue; for (Instruction &II : BB) { auto *AI = dyn_cast<AllocaInst>(&II); if (!AI) continue; // Find the pair of life time markers for address 'Addr' that are either // defined inside the outline region or can legally be shrinkwrapped into // the outline region. If there are not other untracked uses of the // address, return the pair of markers if found; otherwise return a pair // of nullptr. auto GetLifeTimeMarkers = [&](Instruction *Addr, bool &SinkLifeStart, bool &HoistLifeEnd) -> std::pair<Instruction *, Instruction *> { Instruction *LifeStart = nullptr, *LifeEnd = nullptr; for (User *U : Addr->users()) { IntrinsicInst *IntrInst = dyn_cast<IntrinsicInst>(U); if (IntrInst) { if (IntrInst->getIntrinsicID() == Intrinsic::lifetime_start) { // Do not handle the case where AI has multiple start markers. if (LifeStart) return std::make_pair<Instruction *>(nullptr, nullptr); LifeStart = IntrInst; } if (IntrInst->getIntrinsicID() == Intrinsic::lifetime_end) { if (LifeEnd) return std::make_pair<Instruction *>(nullptr, nullptr); LifeEnd = IntrInst; } continue; } // Find untracked uses of the address, bail. if (!definedInRegion(Blocks, U)) return std::make_pair<Instruction *>(nullptr, nullptr); } if (!LifeStart || !LifeEnd) return std::make_pair<Instruction *>(nullptr, nullptr); SinkLifeStart = !definedInRegion(Blocks, LifeStart); HoistLifeEnd = !definedInRegion(Blocks, LifeEnd); // Do legality Check. if ((SinkLifeStart || HoistLifeEnd) && !isLegalToShrinkwrapLifetimeMarkers(Addr)) return std::make_pair<Instruction *>(nullptr, nullptr); // Check to see if we have a place to do hoisting, if not, bail. if (HoistLifeEnd && !ExitBlock) return std::make_pair<Instruction *>(nullptr, nullptr); return std::make_pair(LifeStart, LifeEnd); }; bool SinkLifeStart = false, HoistLifeEnd = false; auto Markers = GetLifeTimeMarkers(AI, SinkLifeStart, HoistLifeEnd); if (Markers.first) { if (SinkLifeStart) SinkCands.insert(Markers.first); SinkCands.insert(AI); if (HoistLifeEnd) HoistCands.insert(Markers.second); continue; } // Follow the bitcast. Instruction *MarkerAddr = nullptr; for (User *U : AI->users()) { if (U->stripInBoundsConstantOffsets() == AI) { SinkLifeStart = false; HoistLifeEnd = false; Instruction *Bitcast = cast<Instruction>(U); Markers = GetLifeTimeMarkers(Bitcast, SinkLifeStart, HoistLifeEnd); if (Markers.first) { MarkerAddr = Bitcast; continue; } } // Found unknown use of AI. if (!definedInRegion(Blocks, U)) { MarkerAddr = nullptr; break; } } if (MarkerAddr) { if (SinkLifeStart) SinkCands.insert(Markers.first); if (!definedInRegion(Blocks, MarkerAddr)) SinkCands.insert(MarkerAddr); SinkCands.insert(AI); if (HoistLifeEnd) HoistCands.insert(Markers.second); } } } }
void RegionExtractor::findInputsOutputs(ValueSet &Inputs, ValueSet &Outputs) const { for (SetVector<BasicBlock *>::const_iterator I = Blocks.begin(), E = Blocks.end(); I != E; ++I) { BasicBlock *BB = *I; // If a used value is defined outside the region, it's an input. If an // instruction is used outside the region, it's an output. for (BasicBlock::iterator II = BB->begin(), IE = BB->end(); II != IE; ++II) { for (User::op_iterator OI = II->op_begin(), OE = II->op_end(); OI != OE; ++OI) if (definedInCaller(Blocks, *OI)) Inputs.insert(*OI); #if LLVM_VERSION_MINOR == 5 for (User *U : II->users()) if (!definedInRegion(Blocks, U)) { #else for (Value::use_iterator UI = II->use_begin(), UE = II->use_end(); UI != UE; ++UI) if (!definedInRegion(Blocks, *UI)) { #endif Outputs.insert(II); break; } } } } /// severSplitPHINodes - If a PHI node has multiple inputs from outside of the /// region, we need to split the entry block of the region so that the PHI node /// is easier to deal with. void RegionExtractor::severSplitPHINodes(BasicBlock *&Header) { unsigned NumPredsFromRegion = 0; unsigned NumPredsOutsideRegion = 0; if (Header != &Header->getParent()->getEntryBlock()) { PHINode *PN = dyn_cast<PHINode>(Header->begin()); if (!PN) return; // No PHI nodes. // If the header node contains any PHI nodes, check to see if there is more // than one entry from outside the region. If so, we need to sever the // header block into two. for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) if (Blocks.count(PN->getIncomingBlock(i))) ++NumPredsFromRegion; else ++NumPredsOutsideRegion; // If there is one (or fewer) predecessor from outside the region, we don't // need to do anything special. if (NumPredsOutsideRegion <= 1) return; } // Otherwise, we need to split the header block into two pieces: one // containing PHI nodes merging values from outside of the region, and a // second that contains all of the code for the block and merges back any // incoming values from inside of the region. BasicBlock::iterator AfterPHIs = Header->getFirstNonPHI(); BasicBlock *NewBB = Header->splitBasicBlock(AfterPHIs, Header->getName()+".ce"); // We only want to code extract the second block now, and it becomes the new // header of the region. BasicBlock *OldPred = Header; Blocks.remove(OldPred); Blocks.insert(NewBB); Header = NewBB; // Okay, update dominator sets. The blocks that dominate the new one are the // blocks that dominate TIBB plus the new block itself. if (DT) DT->splitBlock(NewBB); // Okay, now we need to adjust the PHI nodes and any branches from within the // region to go to the new header block instead of the old header block. if (NumPredsFromRegion) { PHINode *PN = cast<PHINode>(OldPred->begin()); // Loop over all of the predecessors of OldPred that are in the region, // changing them to branch to NewBB instead. for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) if (Blocks.count(PN->getIncomingBlock(i))) { TerminatorInst *TI = PN->getIncomingBlock(i)->getTerminator(); TI->replaceUsesOfWith(OldPred, NewBB); } // Okay, everything within the region is now branching to the right block, we // just have to update the PHI nodes now, inserting PHI nodes into NewBB. for (AfterPHIs = OldPred->begin(); isa<PHINode>(AfterPHIs); ++AfterPHIs) { PHINode *PN = cast<PHINode>(AfterPHIs); // Create a new PHI node in the new region, which has an incoming value // from OldPred of PN. PHINode *NewPN = PHINode::Create(PN->getType(), 1 + NumPredsFromRegion, PN->getName()+".ce", NewBB->begin()); NewPN->addIncoming(PN, OldPred); // Loop over all of the incoming value in PN, moving them to NewPN if they // are from the extracted region. for (unsigned i = 0; i != PN->getNumIncomingValues(); ++i) { if (Blocks.count(PN->getIncomingBlock(i))) { NewPN->addIncoming(PN->getIncomingValue(i), PN->getIncomingBlock(i)); PN->removeIncomingValue(i); --i; } } } } }