/// Assign frame object to an unused portion of the stack in the fixed stack /// object range. Return true if the allocation was successful. static inline bool scavengeStackSlot(MachineFrameInfo &MFI, int FrameIdx, bool StackGrowsDown, unsigned MaxAlign, BitVector &StackBytesFree) { if (MFI.isVariableSizedObjectIndex(FrameIdx)) return false; if (StackBytesFree.none()) { // clear it to speed up later scavengeStackSlot calls to // StackBytesFree.none() StackBytesFree.clear(); return false; } unsigned ObjAlign = MFI.getObjectAlignment(FrameIdx); if (ObjAlign > MaxAlign) return false; int64_t ObjSize = MFI.getObjectSize(FrameIdx); int FreeStart; for (FreeStart = StackBytesFree.find_first(); FreeStart != -1; FreeStart = StackBytesFree.find_next(FreeStart)) { // Check that free space has suitable alignment. unsigned ObjStart = StackGrowsDown ? FreeStart + ObjSize : FreeStart; if (alignTo(ObjStart, ObjAlign) != ObjStart) continue; if (FreeStart + ObjSize > StackBytesFree.size()) return false; bool AllBytesFree = true; for (unsigned Byte = 0; Byte < ObjSize; ++Byte) if (!StackBytesFree.test(FreeStart + Byte)) { AllBytesFree = false; break; } if (AllBytesFree) break; } if (FreeStart == -1) return false; if (StackGrowsDown) { int ObjStart = -(FreeStart + ObjSize); LLVM_DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") scavenged at SP[" << ObjStart << "]\n"); MFI.setObjectOffset(FrameIdx, ObjStart); } else { LLVM_DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") scavenged at SP[" << FreeStart << "]\n"); MFI.setObjectOffset(FrameIdx, FreeStart); } StackBytesFree.reset(FreeStart, FreeStart + ObjSize); return true; }
// Returns false if it times out. bool drain(BitVector& unexecuted) { for (size_t index : unexecuted) { execute(index); unexecuted.clear(index); if (shouldTimeOut()) return false; } return true; }
bool LiveIntervals::checkRegMaskInterference(LiveInterval &LI, BitVector &UsableRegs) { if (LI.empty()) return false; LiveInterval::iterator LiveI = LI.begin(), LiveE = LI.end(); // Use a smaller arrays for local live ranges. ArrayRef<SlotIndex> Slots; ArrayRef<const uint32_t*> Bits; if (MachineBasicBlock *MBB = intervalIsInOneMBB(LI)) { Slots = getRegMaskSlotsInBlock(MBB->getNumber()); Bits = getRegMaskBitsInBlock(MBB->getNumber()); } else { Slots = getRegMaskSlots(); Bits = getRegMaskBits(); } // We are going to enumerate all the register mask slots contained in LI. // Start with a binary search of RegMaskSlots to find a starting point. ArrayRef<SlotIndex>::iterator SlotI = std::lower_bound(Slots.begin(), Slots.end(), LiveI->start); ArrayRef<SlotIndex>::iterator SlotE = Slots.end(); // No slots in range, LI begins after the last call. if (SlotI == SlotE) return false; bool Found = false; for (;;) { assert(*SlotI >= LiveI->start); // Loop over all slots overlapping this segment. while (*SlotI < LiveI->end) { // *SlotI overlaps LI. Collect mask bits. if (!Found) { // This is the first overlap. Initialize UsableRegs to all ones. UsableRegs.clear(); UsableRegs.resize(TRI->getNumRegs(), true); Found = true; } // Remove usable registers clobbered by this mask. UsableRegs.clearBitsNotInMask(Bits[SlotI-Slots.begin()]); if (++SlotI == SlotE) return Found; } // *SlotI is beyond the current LI segment. LiveI = LI.advanceTo(LiveI, *SlotI); if (LiveI == LiveE) return Found; // Advance SlotI until it overlaps. while (*SlotI < LiveI->start) if (++SlotI == SlotE) return Found; } }
bool blTerrainProxy::preLight(LightInfo * light) { if(!bool(mObj)) return(false); if(light->getType() != LightInfo::Vector) return(false); mShadowMask.clear(); return(true); }
void RegUsageInfoCollector:: computeCalleeSavedRegs(BitVector &SavedRegs, MachineFunction &MF) { const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering(); const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); // Target will return the set of registers that it saves/restores as needed. SavedRegs.clear(); TFI.determineCalleeSaves(MF, SavedRegs); // Insert subregs. const MCPhysReg *CSRegs = TRI.getCalleeSavedRegs(&MF); for (unsigned i = 0; CSRegs[i]; ++i) { unsigned Reg = CSRegs[i]; if (SavedRegs.test(Reg)) for (MCSubRegIterator SR(Reg, &TRI, false); SR.isValid(); ++SR) SavedRegs.set(*SR); } // Insert any register fully saved via subregisters. for (const TargetRegisterClass *RC : TRI.regclasses()) { if (!RC->CoveredBySubRegs) continue; for (unsigned PReg = 1, PRegE = TRI.getNumRegs(); PReg < PRegE; ++PReg) { if (SavedRegs.test(PReg)) continue; // Check if PReg is fully covered by its subregs. if (!RC->contains(PReg)) continue; // Add PReg to SavedRegs if all subregs are saved. bool AllSubRegsSaved = true; for (MCSubRegIterator SR(PReg, &TRI, false); SR.isValid(); ++SR) if (!SavedRegs.test(*SR)) { AllSubRegsSaved = false; break; } if (AllSubRegsSaved) SavedRegs.set(PReg); } } }
void InteriorLMManager::downloadGLTextures(LM_HANDLE interiorHandle) { AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::downloadGLTextures: invalid interior handle"); InteriorLMInfo * interiorInfo = mInteriors[interiorHandle]; // The bit vector is used to keep track of which lightmap sets need // to be loaded from the shared "base" instance. Every instance // can have it's own lightmap set due to mission lighting. BitVector needTexture; needTexture.setSize(interiorInfo->mNumLightmaps); needTexture.clear(); for(S32 j = interiorInfo->mInstances.size() - 1; j >= 0; j--) { InstanceLMInfo * instanceInfo = interiorInfo->mInstances[j]; for(S32 k = instanceInfo->mLightmapHandles.size() - 1; k >= 0; k--) { // All instances can share the base instances static lightmaps. // Test here to see if we need to load those lightmaps. if ((j == 0) && !needTexture.test(k)) continue; if (!instanceInfo->mLightmapHandles[k]) { needTexture.set(k); continue; } GFXTexHandle texObj = instanceInfo->mLightmapHandles[k]; if (!texObj || !texObj->mBitmap) { needTexture.set(k); continue; } instanceInfo->mLightmapHandles[k].set( texObj->mBitmap, &GFXDefaultPersistentProfile, false, String("Interior Lightmap Handle") ); } } }
void blInteriorProxy::addToShadowVolume(ShadowVolumeBSP * shadowVolume, LightInfo * light, S32 level) { if(light->getType() != LightInfo::Vector) return; ColorF ambient = light->getAmbient(); bool shadowedTree = true; InteriorInstance* interior = dynamic_cast<InteriorInstance*>(getObject()); if (!interior) return; Resource<InteriorResource> mInteriorRes = interior->getResource(); // check if just getting shadow detail if(level == SceneLighting::SHADOW_DETAIL) { shadowedTree = false; level = mInteriorRes->getNumDetailLevels() - 1; } Interior * detail = mInteriorRes->getDetailLevel(level); bool hasAlarm = detail->hasAlarmState(); // make sure surfaces do not get processed more than once BitVector surfaceProcessed; surfaceProcessed.setSize(detail->mSurfaces.size()); surfaceProcessed.clear(); ColorI color = light->getAmbient(); // go through the zones of the interior and grab outside visible surfaces for(U32 i = 0; i < detail->getNumZones(); i++) { Interior::Zone & zone = detail->mZones[i]; for(U32 j = 0; j < zone.surfaceCount; j++) { U32 surfaceIndex = detail->mZoneSurfaces[zone.surfaceStart + j]; // dont reprocess a surface if(surfaceProcessed.test(surfaceIndex)) continue; surfaceProcessed.set(surfaceIndex); Interior::Surface & surface = detail->mSurfaces[surfaceIndex]; // outside visible? if(!(surface.surfaceFlags & Interior::SurfaceOutsideVisible)) continue; // good surface? PlaneF plane = detail->getPlane(surface.planeIndex); if(Interior::planeIsFlipped(surface.planeIndex)) plane.neg(); // project the plane PlaneF projPlane; mTransformPlane(interior->getTransform(), interior->getScale(), plane, &projPlane); // fill with ambient? (need to do here, because surface will not be // added to the SVBSP tree) F32 dot = mDot(projPlane, light->getDirection()); if(dot > -gParellelVectorThresh)// && !(GFX->getPixelShaderVersion() > 0.0) ) { if(shadowedTree) { // alarm lighting GFXTexHandle normHandle = gInteriorLMManager.duplicateBaseLightmap(detail->getLMHandle(), interior->getLMHandle(), detail->getNormalLMapIndex(surfaceIndex)); GFXTexHandle alarmHandle; GBitmap * normLightmap = normHandle->getBitmap(); GBitmap * alarmLightmap = 0; // check if they share the lightmap if(hasAlarm) { if(detail->getNormalLMapIndex(surfaceIndex) != detail->getAlarmLMapIndex(surfaceIndex)) { alarmHandle = gInteriorLMManager.duplicateBaseLightmap(detail->getLMHandle(), interior->getLMHandle(), detail->getAlarmLMapIndex(surfaceIndex)); alarmLightmap = alarmHandle->getBitmap(); } } // // Support for interior light map border sizes. // U32 xlen, ylen, xoff, yoff; U32 lmborder = detail->getLightMapBorderSize(); xlen = surface.mapSizeX + (lmborder * 2); ylen = surface.mapSizeY + (lmborder * 2); xoff = surface.mapOffsetX - lmborder; yoff = surface.mapOffsetY - lmborder; // attemp to light normal and alarm lighting for(U32 c = 0; c < 2; c++) { GBitmap * lightmap = (c == 0) ? normLightmap : alarmLightmap; if(!lightmap) continue; // fill it for(U32 y = 0; y < ylen; y++) { for(U32 x = 0; x < xlen; x++) { ColorI outColor(255, 0, 0, 255); #ifndef SET_COLORS ColorI lmColor(0, 0, 0, 255); lightmap->getColor(xoff + x, yoff + y, lmColor); U32 _r = static_cast<U32>( color.red ) + static_cast<U32>( lmColor.red ); U32 _g = static_cast<U32>( color.green ) + static_cast<U32>( lmColor.green ); U32 _b = static_cast<U32>( color.blue ) + static_cast<U32>( lmColor.blue ); outColor.red = mClamp(_r, 0, 255); outColor.green = mClamp(_g, 0, 255); outColor.blue = mClamp(_b, 0, 255); #endif lightmap->setColor(xoff + x, yoff + y, outColor); } } } } continue; } ShadowVolumeBSP::SVPoly * poly = buildInteriorPoly(shadowVolume, detail, surfaceIndex, light, shadowedTree); // insert it into the SVBSP tree shadowVolume->insertPoly(poly); } } }