Only rematerialize instructions when its safe to.

Only rematerialize an instruction if its inputs are still live
and in registers at the point we're cloning it, which, given the current state of flux in the register allocator, is restricted for
now to just instructions that consume rVmSp, rVmFp, or immediate constants.
Esse commit está contido em:
Edwin Smith
2013-05-01 12:38:35 -07:00
commit de Sara Golemon
commit 08693f9d6f
3 arquivos alterados com 117 adições e 6 exclusões
+28 -6
Ver Arquivo
@@ -1135,6 +1135,26 @@ void LinearScan::rematerialize() {
removeUnusedSpills();
}
// Return true if it's safe to rematerialize inst at reload's position.
bool srcsAreLive(IRInstruction* inst, IRInstruction* reload) {
// It's only ok to rematerialize an instruction if its sources are
// guaranteed to be in known registers at the point we would other wise
// reload its spilled result.
// Although we can inspect each SSAtmp's live range (linear id of its
// definition point and last use), we don't trust that live range given
// the state of the IR after register allocation has inserted spills
// and reloads. So only rematerialize instructions whose sources are
// in registers we trust to be live: rVmSp and rVmFp. Ignore DefConst
// sources because they're implicitly turned into immediates by every
// instruction that uses them.
for (SSATmp* src : inst->getSrcs()) {
if (!src->hasReg(0) && src->inst()->op() != DefConst) return false;
auto reg = src->getReg(0);
if (reg != rVmSp && reg != rVmFp) return false;
}
return true;
};
void LinearScan::rematerializeAux() {
struct State {
SSATmp *sp, *fp;
@@ -1210,12 +1230,14 @@ void LinearScan::rematerializeAux() {
// XXX: could change <newInst> to the non-check version.
// Rematerialize those rematerializable instructions (i.e.,
// isRematerializable returns true) and LdStack.
newInst = spilledInst->clone(m_irFactory);
// The new instruction needn't have an exit label; it must always
// be dominated by the original instruction because reloads are
// inserted just before uses, which must be dominated by the
// original (spilled) def.
newInst->setTaken(nullptr);
if (srcsAreLive(spilledInst, &inst)) {
newInst = spilledInst->clone(m_irFactory);
// The new instruction needn't have an exit label; it must always
// be dominated by the original instruction because reloads are
// inserted just before uses, which must be dominated by the
// original (spilled) def.
newInst->setTaken(nullptr);
}
} else if (curFp) {
// Rematerialize LdLoc.
int loc = findLocal(spilledTmp);
+83
Ver Arquivo
@@ -0,0 +1,83 @@
<?
class KarmaMemcache {
private $keyScoreArr;
private $specs;
function getKeyScores() {
return $this->keyScoreArr;
}
function __construct() {
$this->specs = array(
"login_bruteforce_protection_delta_vetted_datr:3600" =>
// A spec
array('on_block_lockout_time' => 0,
'max_score' => 10000000,
'time_to_decay_max_score' => 100)
);
}
private static function decayScore($a, $b, $c, $d) { return 0; }
/**
* Takes raw data fetched from memcache, applies necessary decay
* function.
*/
private function getFetchedXXX() {
return array(1 /* score */, 0 /*last_occurrence*/, 0
/*last_blocked_time*/);
}
public function getInfo() {
$time = time();
$this->keyScoreArr = array();
foreach ($this->specs as $key => $spec) {
$fetched = $this->getFetchedXXX();
list($score, $last_occurrence, $last_blocked_time) =
array(
idx($fetched, 0, 0),
idx($fetched, 1, 0),
idx($fetched, 2, 0)
);
// FBLogger('test_remat')->warn("score starts $score\n");
if ($time - $last_blocked_time > $spec['on_block_lockout_time']) {
if ($score > $spec['max_score']) {
// Only possible if thresholds were reduced.
$score = 0.5 * $spec['max_score'];
// FBLogger('test_remat')->warn("score halved max case $score\n");
} else {
$score = self::decayScore(
$spec['max_score'],
$spec['time_to_decay_max_score'],
$score,
$last_occurrence
);
// FBLogger('test_remat')->warn("score decayed $score\n");
}
$this->decayedKarmaVectors[$key] = array(
'score' => (double)$score,
'last_occurrence' => (int)$last_occurrence,
'last_blocked_time' => (int)$last_blocked_time
);
// FBLogger('test_remat')->warn("decayed decayed $score: " .
// print_r($this->decayedKarmaVectors[$key], true));
} else {
// In on-block-lockout-interval.
// Don't add to $this->decayedKarmaVectors. That would update the
// timestamp.
}
$this->keyScoreArr[$key] = (double)$score;
if ($this) {
var_dump((double)$score, $this->keyScoreArr[$key]);
}
}
}
}
function main() {
$kc = new KarmaMemcache();
$kc->getInfo();
var_dump($kc->getKeyScores());
}
main();
+6
Ver Arquivo
@@ -0,0 +1,6 @@
float(0)
float(0)
array(1) {
["login_bruteforce_protection_delta_vetted_datr:3600"]=>
float(0)
}