//Read in a KeyGroup (see http://niftools.sourceforge.net/doc/nif/NiKeyframeData.html) void read(NIFStream *nif, bool force=false) { assert(nif); size_t count = nif->getUInt(); if(count == 0 && !force) return; //If we aren't forcing things, make sure that read clears any previous keys if(!force) mKeys.clear(); mInterpolationType = nif->getUInt(); KeyT<T> key; NIFStream &nifReference = *nif; if(mInterpolationType == sLinearInterpolation) { for(size_t i = 0;i < count;i++) { readTimeAndValue(nifReference, key); mKeys.push_back(key); } } else if(mInterpolationType == sQuadraticInterpolation) { for(size_t i = 0;i < count;i++) { readQuadratic(nifReference, key); mKeys.push_back(key); } } else if(mInterpolationType == sTBCInterpolation) { for(size_t i = 0;i < count;i++) { readTBC(nifReference, key); mKeys.push_back(key); } } //XYZ keys aren't actually read here. //data.hpp sees that the last type read was sXYZInterpolation and: // Eats a floating point number, then // Re-runs the read function 3 more times, with force enabled so that the previous values aren't cleared. // When it does that it's reading in a bunch of sLinearInterpolation keys, not sXYZInterpolation. else if(mInterpolationType == sXYZInterpolation) { //Don't try to read XYZ keys into the wrong part if ( count != 1 ) nif->file->fail("XYZ_ROTATION_KEY count should always be '1' . Retrieved Value: "+Ogre::StringConverter::toString(count)); } else if (0 == mInterpolationType) { if (count != 0) nif->file->fail("Interpolation type 0 doesn't work with keys"); } else nif->file->fail("Unhandled interpolation type: "+Ogre::StringConverter::toString(mInterpolationType)); }
bool Legalizer::runOnMachineFunction(MachineFunction &MF) { // If the ISel pipeline failed, do not bother running that pass. if (MF.getProperties().hasProperty( MachineFunctionProperties::Property::FailedISel)) return false; DEBUG(dbgs() << "Legalize Machine IR for: " << MF.getName() << '\n'); init(MF); const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>(); MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr); LegalizerHelper Helper(MF); // FIXME: an instruction may need more than one pass before it is legal. For // example on most architectures <3 x i3> is doubly-illegal. It would // typically proceed along a path like: <3 x i3> -> <3 x i8> -> <8 x i8>. We // probably want a worklist of instructions rather than naive iterate until // convergence for performance reasons. bool Changed = false; MachineBasicBlock::iterator NextMI; using VecType = SmallSetVector<MachineInstr *, 8>; VecType WorkList; VecType CombineList; for (auto &MBB : MF) { for (auto MI = MBB.begin(); MI != MBB.end(); MI = NextMI) { // Get the next Instruction before we try to legalize, because there's a // good chance MI will be deleted. NextMI = std::next(MI); // Only legalize pre-isel generic instructions: others don't have types // and are assumed to be legal. if (!isPreISelGenericOpcode(MI->getOpcode())) continue; unsigned NumNewInsns = 0; WorkList.clear(); CombineList.clear(); Helper.MIRBuilder.recordInsertions([&](MachineInstr *MI) { // Only legalize pre-isel generic instructions. // Legalization process could generate Target specific pseudo // instructions with generic types. Don't record them if (isPreISelGenericOpcode(MI->getOpcode())) { ++NumNewInsns; WorkList.insert(MI); CombineList.insert(MI); } }); WorkList.insert(&*MI); LegalizerCombiner C(Helper.MIRBuilder, MF.getRegInfo(), Helper.getLegalizerInfo()); bool Changed = false; LegalizerHelper::LegalizeResult Res; do { assert(!WorkList.empty() && "Expecting illegal ops"); while (!WorkList.empty()) { NumNewInsns = 0; MachineInstr *CurrInst = WorkList.pop_back_val(); Res = Helper.legalizeInstrStep(*CurrInst); // Error out if we couldn't legalize this instruction. We may want to // fall back to DAG ISel instead in the future. if (Res == LegalizerHelper::UnableToLegalize) { Helper.MIRBuilder.stopRecordingInsertions(); if (Res == LegalizerHelper::UnableToLegalize) { reportGISelFailure(MF, TPC, MORE, "gisel-legalize", "unable to legalize instruction", *CurrInst); return false; } } Changed |= Res == LegalizerHelper::Legalized; // If CurrInst was legalized, there's a good chance that it might have // been erased. So remove it from the Combine List. if (Res == LegalizerHelper::Legalized) CombineList.remove(CurrInst); #ifndef NDEBUG if (NumNewInsns) for (unsigned I = WorkList.size() - NumNewInsns, E = WorkList.size(); I != E; ++I) DEBUG(dbgs() << ".. .. New MI: " << *WorkList[I];); #endif } // Do the combines. while (!CombineList.empty()) { NumNewInsns = 0; MachineInstr *CurrInst = CombineList.pop_back_val(); SmallVector<MachineInstr *, 4> DeadInstructions; Changed |= C.tryCombineInstruction(*CurrInst, DeadInstructions); for (auto *DeadMI : DeadInstructions) { DEBUG(dbgs() << ".. Erasing Dead Instruction " << *DeadMI); CombineList.remove(DeadMI); WorkList.remove(DeadMI); DeadMI->eraseFromParent(); } #ifndef NDEBUG if (NumNewInsns) for (unsigned I = CombineList.size() - NumNewInsns, E = CombineList.size(); I != E; ++I) DEBUG(dbgs() << ".. .. Combine New MI: " << *CombineList[I];); #endif } } while (!WorkList.empty()); Helper.MIRBuilder.stopRecordingInsertions(); }