Expression ValueTable::create_expression(Instruction *I) { Expression e; e.type = I->getType(); e.opcode = I->getOpcode(); for (Instruction::op_iterator OI = I->op_begin(), OE = I->op_end(); OI != OE; ++OI) e.varargs.push_back(lookup_or_add(*OI)); if (I->isCommutative()) { // Ensure that commutative instructions that only differ by a permutation // of their operands get the same value number by sorting the operand value // numbers. Since all commutative instructions have two operands it is more // efficient to sort by hand rather than using, say, std::sort. assert(I->getNumOperands() == 2 && "Unsupported commutative instruction!"); if (e.varargs[0] > e.varargs[1]) std::swap(e.varargs[0], e.varargs[1]); } if (CmpInst *C = dyn_cast<CmpInst>(I)) { // Sort the operand value numbers so x<y and y>x get the same value number. CmpInst::Predicate Predicate = C->getPredicate(); if (e.varargs[0] > e.varargs[1]) { std::swap(e.varargs[0], e.varargs[1]); Predicate = CmpInst::getSwappedPredicate(Predicate); } e.opcode = (C->getOpcode() << 8) | Predicate; } else if (InsertValueInst *E = dyn_cast<InsertValueInst>(I)) { for (InsertValueInst::idx_iterator II = E->idx_begin(), IE = E->idx_end(); II != IE; ++II) e.varargs.push_back(*II); } return e; }
void G1StringDedupTable::deduplicate(oop java_string, G1StringDedupStat& stat) { assert(java_lang_String::is_instance(java_string), "Must be a string"); NoSafepointVerifier nsv; stat.inc_inspected(); typeArrayOop value = java_lang_String::value(java_string); if (value == NULL) { // String has no value stat.inc_skipped(); return; } bool latin1 = java_lang_String::is_latin1(java_string); unsigned int hash = 0; if (use_java_hash()) { // Get hash code from cache hash = java_lang_String::hash(java_string); } if (hash == 0) { // Compute hash hash = hash_code(value, latin1); stat.inc_hashed(); if (use_java_hash() && hash != 0) { // Store hash code in cache java_lang_String::set_hash(java_string, hash); } } typeArrayOop existing_value = lookup_or_add(value, latin1, hash); if (existing_value == value) { // Same value, already known stat.inc_known(); return; } // Get size of value array uintx size_in_bytes = value->size() * HeapWordSize; stat.inc_new(size_in_bytes); if (existing_value != NULL) { // Enqueue the reference to make sure it is kept alive. Concurrent mark might // otherwise declare it dead if there are no other strong references to this object. G1SATBCardTableModRefBS::enqueue(existing_value); // Existing value found, deduplicate string java_lang_String::set_value(java_string, existing_value); if (G1CollectedHeap::heap()->is_in_young(value)) { stat.inc_deduped_young(size_in_bytes); } else { stat.inc_deduped_old(size_in_bytes); } } }
uint32_t ValueTable::lookup_or_add_call(CallInst *C) { Function *F = C->getCalledFunction(); if (F != NULL && F->hasName() && F->getName().startswith(GLOBAL_FN_GLOBAL_ADDR)) { Value *op = C->getOperand(0); DenseMap<Value*, uint32_t>::const_iterator VI = valueNumbering.find(op); if (VI != valueNumbering.end()) { return VI->second; } else { // Not numbered yet return lookup_or_add(op); } } else { valueNumbering[C] = nextValueNumber; return nextValueNumber++; } }